string.charAt (x) или string [x]?

247

Есть ли какая-либо причина, по которой я должен использовать string.charAt(x)вместо обозначения скобки string[x]?

смеситель
источник
3
Слово предостережения : использование синтаксиса для смайликов или любых других символов Юникода после Базового многоязычного плана BPM (также известное как «Астральный план» ) "😃".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 против индексатора в Chrome, когда строка помещена в объект. Я знаю, что это не совсем актуально, но все же стоит отметить. jsfiddle.net/mdasxxd2
сидерит Zackwehdex
5
Более точный тест (benchmark.js) esbench.com/bench/579609a0db965b9a00965b9e
NoNameProvided
3
Несмотря на то, что этот рейтинг набрал наибольшее количество баллов, этот ответ (2019 г.) значительно устарел. Ответ ниже, цитирующий MDN, следует использовать вместо этого.
Скотт Мартин
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 еще не поддерживается во ВСЕХ браузерах, но поддерживается в MOST-браузерах: имеется в виду IE9 и выше и все версии Chrome / Firefox: kangax.github.io/compat-table/es5/#Property_access_on_strings Никакой функции JS не будет быть на 100% поддерживаемым, и я чувствую, что отказ от использования функций ECMA 5 оставит нас в прошлом навсегда ...
Дэнни Р
84

Они могут дать разные результаты в крайних случаях.

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

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

Функция charAt зависит от того, как индекс преобразуется в число в спецификации .

MarkG
источник
Также 'hello'[undefined] // undefinedи'hello'.charAt(undefined) //h
Хуан Мендес
3
nullработает как undefined, но вижу это: "hello"["00"] // undefinedно "hello".charAt("00") // "h"и"hello"["0"] // "h"
Panzi
11
Это искренне убеждает меня продолжать использовать [].
Приближается к
Это также означает, что .charAt()выполняет дополнительное преобразование своего параметра в Number. К вашему сведению, в настоящее время почти нет разницы в производительности.
Константин Ван
7
Этот ответ должен двигаться вверх, он фактически объясняет, что есть разница между двумя методами. Другие ответы говорят о совместимости для IE7 (я имею в виду на самом деле?), В то время как этот ответ объясняет очень реальную ловушку.
Шторм Мюллер
11

String.charAt () является оригинальным стандартом и работает во всех браузерах. В IE 8+ и других браузерах вы можете использовать скобочные обозначения для доступа к символам, но IE 7 и ниже не поддерживает его.

Если кто-то действительно хочет использовать скобочную нотацию в IE 7, целесообразно преобразовать строку в массив с помощью, str.split('')а затем использовать ее как массив, совместимый с любым браузером.

var testString = "Hello"; 
var charArr = testString.split("");
charArr[1]; // "e"
CharithJ
источник
5
IE поддерживает скобочные обозначения от 8 лет.
mrec
3
Этот метод ломается при работе с Unicode: mathiasbynens.be/notes/javascript-unicode
Джереми Дж. Старчер
Этот метод был бы неэффективен при работе с действительно большими строками, потому что он дублировал бы данные в памяти (исходная строка и массив).
Даниэль
8

Очень интересный результат, когда вы проверяете метод доступа к строковому индексу против charAt()метода. Кажется, Chrome - единственный браузер, который любит charAtбольше.

CharAt против индекса 1

ChartAt vs index 2

ChartAt vs index 3

Арман Макхитариан
источник
1
Это больше не так. indexв хроме тоже быстрее.
Мако-Тако
5

Есть разница, когда вы пытаетесь получить доступ к индексу, который находится за пределами или не является целым числом.

string[x]возвращает символ в xth-й позиции в stringif, если 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 неизменны .

Дональд Дак
источник