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

246

Existe algum motivo para eu usar em string.charAt(x)vez da notação de colchete string[x]?

Liquidificador
fonte
3
Palavra de cautela : usando sintaxe para emojis ou quaisquer outros caracteres Unicode últimos o Basic Multilingual Plane BPM (AKA o "Plano Astral" ) "😃".charAt(0)irá retornar um carácter inutilizável
KyleMit

Respostas:

243

A notação de colchete agora funciona em todos os principais navegadores, exceto no IE7 e abaixo.

// Bracket Notation
"Test String1"[6]

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

Costumava ser uma má idéia usar colchetes, por esses motivos ( Fonte ):

Essa notação não funciona no IE7. O primeiro trecho de código retornará indefinido no IE7. Se você usar a notação de colchete para cadeias de caracteres em todo o seu código e quiser migrar para .charAt(pos), isso é um problema: os colchetes são usados ​​em todo o código e não há uma maneira fácil de detectar se isso é para uma cadeia de caracteres ou uma matriz / objeto.

Você não pode definir o personagem usando esta notação. Como não há nenhum aviso, isso é realmente confuso e frustrante. Se você estivesse usando a .charAt(pos)função, não teria tentado fazê-lo.

Brian Webster
fonte
21
É verdade que a notação não funciona no IE7, mas isso não é uma grande desvantagem hoje em dia. Enquanto isso, os benchmarks que eu fiz mostraram uma redução de três vezes no desempenho ao usar o charAt vs o indexador no Chrome quando a string está dentro de um objeto. Eu sei que isso não é realmente relevante, mas ainda vale a pena notar. jsfiddle.net/mdasxxd2
Siderite Zackwehdex
5
Um teste mais preciso (benchmark.js) esbench.com/bench/579609a0db965b9a00965b9e
NoNameProvided
3
Apesar de ser a mais pontuada, esta resposta está agora (2019) significativamente desatualizada. A resposta abaixo citando o MDN deve ser referenciada.
Scott Martin
97

Do MDN :

Existem duas maneiras de acessar um caractere individual em uma sequência. O primeiro é o charAtmétodo, parte do ECMAScript 3:

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

A outra maneira é tratar a string como um objeto de matriz, em que cada caractere individual corresponde a um índice numérico. Isso é suportado pela maioria dos navegadores desde a primeira versão, exceto pelo IE. Foi padronizado no ECMAScript 5:

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

A segunda maneira requer o suporte ao ECMAScript 5 (e não é suportado em alguns navegadores mais antigos).

Nos dois casos, tentar alterar um caractere individual não funcionará, pois as strings são imutáveis, ou seja, suas propriedades não são "graváveis" nem "configuráveis".

  • str.charAt(i) é melhor do ponto de vista da compatibilidade se a compatibilidade com o IE6 / IE7 for necessária.
  • str[i] é mais moderno e funciona no IE8 + e em todos os outros navegadores (todos Edge / Firefox / Chrome, Safari 2+, todos iOS / Android).
Matt Ball
fonte
19
É verdade que o ECMA 5 ainda não é suportado em TODOS os navegadores, mas é suportado na maioria dos navegadores: significando IE9 e acima e todas as versões do Chrome / Firefox: kangax.github.io/compat-table/es5/#Property_access_on_strings Nenhum recurso JS jamais será ser 100% compatível, e eu sinto que evitando o uso de ECMA 5 características vai nos deixar no passado para sempre ...
Danny R
83

Eles podem dar resultados diferentes em casos extremos.

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

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

A função charAt depende de como o índice é convertido em um número na especificação .

MarkG
fonte
Também 'hello'[undefined] // undefinede'hello'.charAt(undefined) //h
Juan Mendes
3
nullfunciona assim undefined, mas veja isto: "hello"["00"] // undefinedmas "hello".charAt("00") // "h"e"hello"["0"] // "h"
panzi 27/02
11
Isso sinceramente me convence a continuar usando [].
ApproachingDarknessFish
Isso também significa que .charAt()realiza uma conversão extra para seu parâmetro em a Number. Para sua informação, quase não há diferença de desempenho atualmente.
Константин Ван
7
Essa resposta deve subir, na verdade explica que há uma diferença entre os 2 métodos. As outras respostas falam sobre compatibilidade com o IE7 (quero dizer mesmo?), Enquanto essa resposta explica uma armadilha muito real.
Storm Muller
11

String.charAt () é o padrão original e funciona em todos os navegadores. No IE 8+ e em outros navegadores, você pode usar a notação de colchete para acessar caracteres, mas o IE 7 e abaixo não o suportam.

Se alguém realmente deseja usar a notação de colchete no IE 7, é aconselhável converter a string em uma matriz usando str.split('')e depois usá-la como uma matriz, compatível com qualquer navegador.

var testString = "Hello"; 
var charArr = testString.split("");
charArr[1]; // "e"
CharithJ
fonte
5
O IE suporta notação de colchete a partir de 8.
MREC
3
Este método pausas quando se lida com Unicode: mathiasbynens.be/notes/javascript-unicode
Jeremy J Starcher
Este método seria ineficiente ao lidar com cadeias realmente grandes, porque duplicaria os dados na memória (a cadeia original e a matriz).
Daniel
8

Resultado muito interessante quando você testa o acessador de índice de strings versus o charAt()método Parece que o Chrome é o único navegador que gosta charAtmais.

CharAt vs índice 1

ChartAt vs índice 2

ChartAt vs índice 3

Arman McHitarian
fonte
1
Este não é mais o caso. indextambém é muito mais rápido no chrome.
Mako-taco
5

Há uma diferença quando você tenta acessar um índice que está fora dos limites ou não é um número inteiro.

string[x]retorna o caractere na xposição th em stringse xfor um número inteiro entre 0 e string.length-1, e retorna undefinedcaso contrário.

string.charAt(x)converte xpara um número inteiro usando o processo explicado aqui (que basicamente arredonda xpara baixo se xé um número não inteiro e retorna 0 se parseInt(x)for NaN) e, em seguida, retorna o caractere nessa posição se o número inteiro estiver entre 0 e string.length-1, e retorna uma string vazia, caso contrário .

aqui estão alguns exemplos:

"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

Outra diferença é que atribuir a string[x]não faz nada (o que pode ser confuso) e atribuir a string.charAt(x)é um erro (como esperado):

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

A razão pela qual atribuir a string[x]não funciona é porque as strings Javascript são imutáveis .

Pato Donald
fonte