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

246

¿Hay alguna razón que deba usar en string.charAt(x)lugar de la notación de corchetes string[x]?

Licuadora
fuente
3
Advertencia : el uso de sintaxis para emojis o cualquier otro carácter unicode más allá del BPM del plano multilingüe básico (también conocido como "plano astral" ) "😃".charAt(0)devolverá un carácter inutilizable
KyleMit

Respuestas:

243

La notación de corchetes ahora funciona en todos los principales navegadores, excepto IE7 y versiones inferiores.

// Bracket Notation
"Test String1"[6]

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

Solía ​​ser una mala idea usar corchetes, por estos motivos ( Fuente ):

Esta notación no funciona en IE7. El primer fragmento de código volverá indefinido en IE7. Si utiliza la notación de corchetes para cadenas en todo el código y desea migrar .charAt(pos), esto es un verdadero dolor: los corchetes se usan en todo el código y no hay una manera fácil de detectar si es para una cadena o una matriz / objeto.

No puede establecer el carácter con esta notación. Como no hay advertencia de ningún tipo, esto es realmente confuso y frustrante. Si estuviera utilizando la .charAt(pos)función, no habría tenido la tentación de hacerlo.

Brian Webster
fuente
21
Es cierto que la notación no funciona en IE7, pero eso no es una gran desventaja hoy en día. Mientras tanto, los puntos de referencia que hice mostraron una disminución de tres veces en el rendimiento al usar charAt vs indexer en Chrome cuando la cadena se encuadra en un objeto. Sé que eso no es realmente relevante, pero aún vale la pena señalarlo. jsfiddle.net/mdasxxd2
Zackwehdex
55
Una prueba más precisa (benchmark.js) esbench.com/bench/579609a0db965b9a00965b9e
NoNameProvided
3
A pesar de ser el mejor calificado, esta respuesta está ahora (2019) significativamente desactualizada. En su lugar, debe mencionarse la respuesta a continuación que cita MDN .
Scott Martin
97

De MDN :

Hay dos formas de acceder a un carácter individual en una cadena. El primero es el charAtmétodo, parte de ECMAScript 3:

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

La otra forma es tratar la cadena como un objeto tipo matriz, donde cada carácter individual corresponde a un índice numérico. Esto ha sido admitido por la mayoría de los navegadores desde su primera versión, excepto IE. Fue estandarizado en ECMAScript 5:

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

La segunda forma requiere compatibilidad con ECMAScript 5 (y no es compatible con algunos navegadores más antiguos).

En ambos casos, intentar cambiar un carácter individual no funcionará, ya que las cadenas son inmutables, es decir, sus propiedades no son ni "grabables" ni "configurables".

  • str.charAt(i) es mejor desde una perspectiva de compatibilidad si se requiere compatibilidad con IE6 / IE7.
  • str[i] es más moderno y funciona en IE8 + y en todos los demás navegadores (todos Edge / Firefox / Chrome, Safari 2+, todos iOS / Android).
Matt Ball
fuente
19
Es cierto que ECMA 5 aún no es compatible con TODOS los navegadores, pero ES compatible con la MAYORÍA de los navegadores: es decir, IE9 y superior y todas las versiones de Chrome / Firefox: kangax.github.io/compat-table/es5/#Property_access_on_strings Ninguna función JS jamás ser 100% compatible, y creo que evitar el uso de las funciones de ECMA 5 nos dejará en el pasado para siempre ...
Danny R
83

Pueden dar resultados diferentes en casos extremos.

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

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

La función charAt depende de cómo se convierte el índice en un Número en la especificación .

MarkG
fuente
También 'hello'[undefined] // undefinedy'hello'.charAt(undefined) //h
Juan Mendes
3
nullfunciona como undefined, pero mira esto: "hello"["00"] // undefinedpero "hello".charAt("00") // "h"y"hello"["0"] // "h"
panzi
11
Esto de todo corazón me convence de seguir usando [].
ApproachingDarknessFish
Esto también significa que .charAt()realiza una conversión adicional para su parámetro en a Number. Para su información, casi no hay diferencia de rendimiento hoy en día.
Константин Ван
77
Esta respuesta debería avanzar, en realidad explica que hay una diferencia entre los 2 métodos. Las otras respuestas hablan de compatibilidad para IE7 (¿quiero decir realmente?), Mientras que esta respuesta explica una trampa muy real.
Storm Muller
11

String.charAt () es el estándar original y funciona en todos los navegadores. En IE 8+ y otros navegadores, puede usar la notación de corchetes para acceder a los caracteres, pero IE 7 y versiones posteriores no lo admitieron.

Si alguien realmente quiere usar la notación de corchetes en IE 7, es aconsejable convertir la cadena a una matriz usando str.split('')y luego usarla como una matriz, compatible con cualquier navegador.

var testString = "Hello"; 
var charArr = testString.split("");
charArr[1]; // "e"
CharithJ
fuente
55
IE admite la notación de corchetes desde 8 en adelante.
mrec
3
Este método se rompe cuando se trata con Unicode: mathiasbynens.be/notes/javascript-unicode
Jeremy J Starcher
Este método sería ineficiente cuando se trata de cadenas realmente grandes porque duplicaría los datos en la memoria (la cadena original y la matriz).
Daniel
8

Resultado muy interesante cuando prueba el descriptor de acceso al índice de cadena frente al charAt()método Parece que Chrome es el único navegador que le gusta charAtmás.

CharAt vs índice 1

ChartAt vs índice 2

ChartAt vs índice 3

Arman McHitarian
fuente
1
Este ya no es el caso. indextambién es mucho más rápido en cromo.
mako-taco
5

Hay una diferencia cuando intenta acceder a un índice que está fuera de los límites o no es un número entero.

string[x]devuelve el carácter en la xposición th en stringif xes un número entero entre 0 y string.length-1, y devuelve lo undefinedcontrario.

string.charAt(x)se convierte xen un entero utilizando el proceso explicado aquí (que básicamente redondea xhacia abajo si xes un número no entero y devuelve 0 si parseInt(x)es NaN) y luego devuelve el carácter en esa posición si el entero está entre 0 y string.length-1, de lo contrario, devuelve una cadena vacía .

Aquí hay unos ejemplos:

"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

Otra diferencia es que asignar a string[x]no hace nada (lo que puede ser confuso) y asignar string.charAt(x)es un error (como se esperaba):

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

La razón por la que asignar a string[x]no funciona es porque las cadenas de Javascript son inmutables .

Pato Donald
fuente