string.charAt (x) czy string [x]?

247

Czy jest jakiś powód, dla którego powinienem użyć string.charAt(x)zamiast notacji w nawiasie string[x]?

Mikser
źródło
3
Słowo ostrzeżenia : użycie dowolnej składni dla emoji lub dowolnych innych znaków Unicode poza Basic Multilingual Plane BPM (AKA to „Astral Plane” ) "😃".charAt(0)zwróci postać, której nie można
użyć

Odpowiedzi:

243

Notacja w nawiasach działa teraz we wszystkich głównych przeglądarkach, z wyjątkiem IE7 i niższych.

// Bracket Notation
"Test String1"[6]

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

Używanie nawiasów to zły pomysł z następujących powodów ( Źródło ):

Ta notacja nie działa w IE7. Pierwszy fragment kodu zwróci niezdefiniowany w IE7. Jeśli używasz notacji nawiasowej dla ciągów znaków w całym kodzie i chcesz do niej migrować .charAt(pos), to jest prawdziwy problem: nawiasy są używane w całym kodzie i nie ma łatwego sposobu na wykrycie, czy jest to ciąg, czy tablica / obiekt.

Nie możesz ustawić postaci za pomocą tej notacji. Ponieważ nie ma żadnych ostrzeżeń, jest to naprawdę mylące i frustrujące. Gdybyś używał tej .charAt(pos)funkcji, nie miałbyś pokusy, aby to zrobić.

Brian Webster
źródło
21
To prawda, że ​​notacja nie działa w IE7, ale obecnie nie jest to duża wada. Tymczasem przeprowadzone przeze mnie testy porównawcze wykazały trzykrotny spadek wydajności podczas używania charAt vs. indexer w Chrome, gdy ciąg znaków jest zapakowany w obiekcie. Wiem, że to nie jest tak naprawdę istotne, ale wciąż warte odnotowania. jsfiddle.net/mdasxxd2
Siderite Zackwehdex
5
Bardziej dokładny test (benchmark.js) esbench.com/bench/579609a0db965b9a00965b9e
NoNamePostepiono
3
Pomimo tego, że uzyskała najwyższą punktację, ta odpowiedź jest obecnie (2019) znacznie nieaktualna. Zamiast tego należy odnieść się do odpowiedzi podającej MDN .
Scott Martin
97

Z MDN :

Istnieją dwa sposoby uzyskania dostępu do pojedynczego znaku w ciągu. Pierwszą jest charAtmetoda będąca częścią ECMAScript 3:

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

Innym sposobem jest traktowanie łańcucha jako obiektu tablicowego, w którym każdy pojedynczy znak odpowiada indeksowi numerycznemu. Jest to obsługiwane przez większość przeglądarek od ich pierwszej wersji, z wyjątkiem IE. Został ustandaryzowany w ECMAScript 5:

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

Drugi sposób wymaga obsługi ECMAScript 5 (i nie jest obsługiwany w niektórych starszych przeglądarkach).

W obu przypadkach próba zmiany pojedynczego znaku nie zadziała, ponieważ ciągi są niezmienne, tzn. Ich właściwości nie są ani „zapisywalne”, ani „konfigurowalne”.

  • str.charAt(i) jest lepszy z punktu widzenia kompatybilności, jeśli wymagana jest kompatybilność z IE6 / IE7.
  • str[i] jest bardziej nowoczesny i działa w IE8 + i wszystkich innych przeglądarkach (wszystkie Edge / Firefox / Chrome, Safari 2+, wszystkie iOS / Android).
Matt Ball
źródło
19
To prawda, że ​​ECMA 5 nie jest jeszcze obsługiwany we WSZYSTKICH przeglądarkach, ale jest obsługiwany w większości MOST: co oznacza IE9 i nowsze wersje oraz wszystkie wersje Chrome / Firefox: kangax.github.io/compat-table/es5/#Property_access_on_strings Żadna funkcja JS nigdy być w 100% wspierany i uważam, że unikanie korzystania z funkcji ECMA 5 pozostawi nas w przeszłości na zawsze ...
Danny R
83

Mogą dawać różne wyniki w przypadkach krawędzi.

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

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

Funkcja charAt zależy od tego, w jaki sposób indeks jest konwertowany na liczbę w specyfikacji .

MarkG
źródło
Również 'hello'[undefined] // undefinedi'hello'.charAt(undefined) //h
Juan Mendes
3
nulldziała jak undefined, ale zobacz to: "hello"["00"] // undefinedale "hello".charAt("00") // "h"i"hello"["0"] // "h"
panzi
11
To z całego serca przekonuje mnie do dalszego używania [].
ApproachingDarknessFish
Oznacza to również, że .charAt()wykonuje dodatkową konwersję swojego parametru na Number. Do Twojej wiadomości, obecnie nie ma prawie żadnej różnicy w wydajności.
Константин Ван
7
Ta odpowiedź powinna wzrosnąć, tak naprawdę wyjaśnia, że ​​istnieje różnica między 2 metodami. Inne odpowiedzi mówią o kompatybilności dla IE7 (mam na myśli naprawdę?), Podczas gdy ta odpowiedź wyjaśnia bardzo poważną pułapkę.
Storm Muller,
11

String.charAt () jest oryginalnym standardem i działa we wszystkich przeglądarkach. W IE 8+ i innych przeglądarkach możesz używać notacji w nawiasach, aby uzyskać dostęp do znaków, ale IE 7 i niższe nie obsługują tego.

Jeśli ktoś naprawdę chce użyć notacji nawiasowej w IE 7, mądrze jest przekonwertować ciąg znaków na tablicę za pomocą, str.split('')a następnie użyć go jako tablicy kompatybilnej z dowolną przeglądarką.

var testString = "Hello"; 
var charArr = testString.split("");
charArr[1]; // "e"
CharithJ
źródło
5
IE obsługuje notację w nawiasie od 8.
mrec
3
Ta metoda nie działa w
Jeremy J Starcher
Ta metoda byłaby nieefektywna w przypadku naprawdę dużych łańcuchów, ponieważ kopiowałaby dane w pamięci (oryginalny łańcuch i tablicę).
Daniel,
8

Bardzo interesujący wynik podczas testowania modułu indeksującego ciąg znaków w porównaniu z charAt()metodą. Wygląda na to, że Chrome jest jedyną przeglądarką, która lubi charAtwięcej.

CharAt vs indeks 1

ChartAt vs. indeks 2

ChartAt vs. indeks 3

Arman McHitarian
źródło
1
Tak już nie jest. indexjest też znacznie szybszy w chrome.
mako-taco
5

Jest różnica, gdy próbujesz uzyskać dostęp do indeksu, który jest poza zakresem lub nie jest liczbą całkowitą.

string[x]zwraca znak na xpozycji th w stringif, która xjest liczbą całkowitą od 0 do string.length-1, i zwraca undefinedinaczej.

string.charAt(x)konwertuje xna liczbę całkowitą przy użyciu opisanego tutaj procesu (który zasadniczo zaokrągla w xdół, jeśli xjest liczbą niecałkowitą i zwraca 0, jeśli parseInt(x)jest NaN), a następnie zwraca znak w tej pozycji, jeśli liczba całkowita jest między 0 string.length-1, a w przeciwnym razie zwraca pusty ciąg .

Oto kilka przykładów:

"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

Inną różnicą jest to, że przypisanie do string[x]niczego nie robi (co może być mylące), a przypisanie do string.charAt(x)jest błędem (zgodnie z oczekiwaniami):

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

Powodem, dla którego przypisywanie do string[x]nie działa, jest to, że ciągi JavaScript są niezmienne .

Kaczor Donald
źródło