string.charAt (x) หรือสตริง [x]?


247

มีเหตุผลใดบ้างที่ฉันควรใช้string.charAt(x)แทนเครื่องหมายวงเล็บstring[x]?


3
คำเตือน : การใช้ไวยากรณ์สำหรับ emojis หรืออักขระยูนิโค้ดอื่น ๆ ที่ผ่านBasic Multilingual Plane BPM (AKA the "Astral Plane" ) "😃".charAt(0)จะส่งคืนอักขระที่ใช้ไม่ได้
KyleMit

คำตอบ:


243

เครื่องหมายวงเล็บตอนนี้ทำงานบนเบราว์เซอร์หลักทั้งหมดยกเว้น IE7 และด้านล่าง

// Bracket Notation
"Test String1"[6]

// charAt Implementation
"Test String1".charAt(6)

มันเคยเป็นความคิดที่ดีที่จะใช้วงเล็บด้วยเหตุผลเหล่านี้ ( ที่มา ):

สัญกรณ์นี้ไม่ทำงานใน IE7 ข้อมูลโค้ดแรกจะส่งคืนไม่ได้กำหนดใน IE7 หากคุณใช้เครื่องหมายวงเล็บสำหรับสตริงที่อยู่เหนือรหัสของคุณและคุณต้องการย้ายไปที่.charAt(pos)นี่เป็นความเจ็บปวดที่แท้จริง: วงเล็บจะใช้กับรหัสของคุณและไม่มีวิธีที่ง่ายในการตรวจสอบว่าเป็นสตริงหรืออาร์เรย์ / วัตถุ.

คุณไม่สามารถตั้งค่าตัวละครโดยใช้สัญลักษณ์นี้ เนื่องจากไม่มีการเตือนใด ๆ สิ่งนี้ทำให้สับสนและหงุดหงิดจริงๆ หากคุณใช้ .charAt(pos)ฟังก์ชั่นคุณจะไม่ถูกล่อลวงให้ทำเช่นนั้น


21
จริงแล้วสัญกรณ์ไม่ทำงานใน IE7 แต่ก็ไม่ได้เป็นข้อเสียอย่างใหญ่หลวงในปัจจุบัน ในขณะเดียวกันมาตรฐานที่ฉันได้แสดงให้เห็นว่าประสิทธิภาพลดลงสามครั้งเมื่อใช้ charAt vs indexer ใน Chrome เมื่อสตริงนั้นถูกวางในวัตถุ ฉันรู้ว่ามันไม่เกี่ยวข้องจริงๆ แต่ก็ยังน่าสังเกต jsfiddle.net/mdasxxd2
Siderite Zackwehdex

5
การทดสอบที่แม่นยำยิ่งขึ้น (benchmark.js) esbench.com/bench/579609a0db965b9a00965b9e
ชื่อให้เมื่อ

3
แม้จะเป็นคะแนนสูงสุดคำตอบนี้คือตอนนี้ (2019) ล้าสมัยอย่างมีนัยสำคัญ คำตอบด้านล่างที่อ้างถึง MDNควรถูกอ้างอิงแทน
Scott Martin

97

จากMDN :

มีสองวิธีในการเข้าถึงอักขระแต่ละตัวในสตริง แรกคือcharAtวิธีการเป็นส่วนหนึ่งของ ECMAScript 3:

return 'cat'.charAt(1); // returns "a"

อีกวิธีหนึ่งคือการใช้สตริงเป็นวัตถุคล้ายอาร์เรย์ซึ่งอักขระแต่ละตัวตรงกับดัชนีตัวเลข เบราว์เซอร์ส่วนใหญ่ได้รับการสนับสนุนตั้งแต่เวอร์ชันแรกยกเว้น IE มันเป็นมาตรฐานใน ECMAScript 5:

return 'cat'[1]; // returns "a"

วิธีที่สองต้องการการสนับสนุน ECMAScript 5 (และไม่รองรับในเบราว์เซอร์รุ่นเก่าบางรุ่น)

ในทั้งสองกรณีความพยายามที่จะเปลี่ยนอักขระแต่ละตัวจะไม่ทำงานเนื่องจากสตริงนั้นไม่เปลี่ยนรูปนั่นคือคุณสมบัติของพวกมันไม่ใช่ทั้ง "เขียนได้" หรือ "กำหนดค่าได้"

  • str.charAt(i) จะดีกว่าจากมุมมองความเข้ากันได้ถ้าต้องการความเข้ากันได้ IE6 / IE7
  • str[i] ทันสมัยกว่าและใช้งานได้ใน IE8 + และเบราว์เซอร์อื่น ๆ ทั้งหมด (Edge / Firefox / Chrome, Safari 2+, iOS / Android ทั้งหมด)

19
จริง ECMA 5 ยังไม่รองรับเบราว์เซอร์ทั้งหมด แต่รองรับเบราว์เซอร์ส่วนใหญ่: หมายถึง IE9 และสูงกว่าและเวอร์ชั่นของ Chrome / Firefox ทั้งหมด: kangax.github.io/compat-table/es5/#Property_access_on_strings ไม่มีคุณสมบัติ JS เลย ได้รับการสนับสนุน 100% และฉันรู้สึกว่าการหลีกเลี่ยงการใช้คุณสมบัติ ECMA 5 จะทำให้เราอยู่ในอดีตตลอดไป ...
Danny R

83

พวกเขาสามารถให้ผลลัพธ์ที่แตกต่างในกรณีขอบ

'hello'[NaN] // undefined
'hello'.charAt(NaN) // 'h'

'hello'[true] //undefined
'hello'.charAt(true) // 'e'

ฟังก์ชั่นจรัสขึ้นอยู่กับว่าดัชนีจะถูกแปลงเป็นจำนวนในสเปค


นอกจากนี้'hello'[undefined] // undefinedและ'hello'.charAt(undefined) //h
Juan Mendes

3
nullทำงานได้เหมือนundefinedแต่เห็นสิ่งนี้"hello"["00"] // undefinedแต่"hello".charAt("00") // "h"และ"hello"["0"] // "h"
panzi

11
ทั้งหมดนี้ทำให้ฉันใช้[]อย่างต่อเนื่อง
ApproachDarknessFish

นี่ก็หมายความว่าการดำเนินการแปลงพิเศษสำหรับพารามิเตอร์เข้าไป.charAt() NumberFYI แทบไม่มีความแตกต่างด้านประสิทธิภาพในปัจจุบัน
КонстантинВан

7
คำตอบนี้ควรเลื่อนขึ้นมันอธิบายได้ว่ามีความแตกต่างระหว่าง 2 วิธี คำตอบอื่น ๆ พูดคุยเกี่ยวกับความเข้ากันได้สำหรับ IE7 (ฉันหมายถึงจริงเหรอ?) ในขณะที่คำตอบนี้อธิบายถึงข้อผิดพลาดที่แท้จริงมาก
Storm Muller

11

String.charAt () เป็นมาตรฐานดั้งเดิมและใช้ได้กับเบราว์เซอร์ทั้งหมด ใน IE 8+ และเบราว์เซอร์อื่นคุณสามารถใช้เครื่องหมายวงเล็บเพื่อเข้าถึงตัวละคร แต่ IE 7 และด้านล่างไม่รองรับ

หากใครต้องการใช้เครื่องหมายวงเล็บใน IE 7 จริง ๆ ก็ควรแปลงสตริงเป็นอาร์เรย์ที่ใช้str.split('')แล้วใช้เป็นอาร์เรย์เข้ากันได้กับเบราว์เซอร์ใด ๆ

var testString = "Hello"; 
var charArr = testString.split("");
charArr[1]; // "e"

5
IE รองรับเครื่องหมายวงเล็บจาก 8 เป็นต้นไป
mrec

3
วิธีนี้แตกเมื่อจัดการกับ Unicode: mathiasbynens.be/notes/javascript-unicode
Jeremy J Starcher

วิธีนี้จะไม่มีประสิทธิภาพเมื่อจัดการกับสตริงที่มีขนาดใหญ่มากเพราะมันจะทำซ้ำข้อมูลในหน่วยความจำ (สตริงเดิมและอาร์เรย์)
แดเนียล

8

ผลลัพธ์ที่น่าสนใจมากเมื่อคุณทดสอบการเข้าถึงดัชนีสตริงเทียบกับcharAt()วิธีการ ดูเหมือนว่า Chrome เป็นเบราว์เซอร์เดียวที่ถูกใจcharAtมากขึ้น

CharAt กับดัชนี 1

ChartAt กับดัชนี 2

ChartAt กับดัชนี 3


1
นี่ไม่ใช่กรณีอีกต่อไป indexโครเมี่ยมก็เร็วขึ้นเช่นกัน
mako-taco

5

มีความแตกต่างเมื่อคุณพยายามเข้าถึงดัชนีซึ่งอยู่นอกขอบเขตหรือไม่ใช่จำนวนเต็ม

string[x]ส่งคืนอักขระที่xตำแหน่ง th stringหากxเป็นจำนวนเต็มระหว่าง 0 ถึงstring.length-1และจะส่งกลับเป็นundefinedอย่างอื่น

string.charAt(x)แปลงxเป็นจำนวนเต็มโดยใช้กระบวนการที่อธิบายไว้ที่นี่ (ซึ่งโดยทั่วไปจะปัดเศษxลงถ้าxไม่ใช่ตัวเลขจำนวนเต็มและส่งคืน 0 ถ้าparseInt(x)มีNaN) จากนั้นส่งคืนอักขระที่ตำแหน่งนั้นถ้าจำนวนเต็มอยู่ระหว่าง 0 ถึงstring.length-1และคืนสตริงว่างเปล่า .

นี่คือตัวอย่างบางส่วน:

"Hello"[313]    //undefined
"Hello".charAt(313)    //"", 313 is out of bounds

"Hello"[3.14]    //undefined
"Hello".charAt(3.14)    //'l', rounds 3.14 down to 3

"Hello"[true]    //undefined
"Hello".charAt(true)    //'e', converts true to the integer 1

"Hello"["World"]    //undefined
"Hello".charAt("World")    //'H', "World" evaluates to NaN, which gets converted to 0

"Hello"[Infinity]    //undefined
"Hello".charAt(Infinity)    //"", Infinity is out of bounds

ความแตกต่างอีกอย่างก็คือการมอบหมายให้string[x]ทำอะไร (ซึ่งอาจทำให้สับสน) และการมอบหมายให้string.charAt(x)เป็นข้อผิดพลาด (ตามที่คาดไว้):

var str = "Hello";
str[0] = 'Y';
console.log(str);    //Still "Hello", the above assignment did nothing
str.charAt(0) = 'Y';    //Error, invalid left-hand side in assignment

เหตุผลที่มอบหมายให้string[x]ไม่ทำงานเป็นเพราะสาย Javascript จะไม่เปลี่ยนรูป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.