Por que eu posso adicionar propriedades nomeadas a um array como se fosse um object?

Os dois trechos de código diferentes a seguir parecem equivalentes a mim:

var myArray = Array(); myArray['A'] = "Athens"; myArray['B'] = "Berlin"; 

e

 var myObject = {'A': 'Athens', 'B':'Berlin'}; 

porque ambos se comportam da mesma forma, e também typeof(myArray) == typeof(myObjects) (ambos produzem ‘object‘).

Existe alguma diferença entre essas variantes?

Praticamente tudo em javascript é um object, então você pode “abusar” de um object Array definindo propriedades arbitrárias nele. Isso deve ser considerado prejudicial embora. Matrizes são para dados numericamente indexados – para chaves não numéricas, use um object.

Aqui está um exemplo mais concreto do porquê de chaves não numéricas não “encheckboxrem” em um Array:

 var myArray = Array(); myArray['A'] = "Athens"; myArray['B'] = "Berlin"; alert(myArray.length); 

Isso não exibirá ‘2’, mas ‘0’ – efetivamente, nenhum elemento foi adicionado à matriz, apenas algumas novas propriedades adicionadas ao object da matriz.

Em matrizes JS são objects, apenas ligeiramente modificados (com mais algumas funções).

Funções como:

 concat every filer forEach join indexOf lastIndexOf map pop push reverse shift slice some sort splice toSource toString unshift valueOf 

Tudo em JavaScript é um object além dos tipos primitivos.

O código

 var myArray = Array(); 

cria uma instância do object Array enquanto

 var myObject = {'A': 'Athens', 'B':'Berlin'}; 

cria uma instância do object Object.

Experimente o seguinte código

 alert(myArray.constructor) alert(myObject.constructor) 

Então você verá que a diferença está no tipo de construtor de objects.

A instância do object Array conterá todas as propriedades e methods do protótipo Array.

Me pensa, eu também metafórico e enigmático com a resposta anterior. Clarificação segue.

Uma instância de Matriz, Booleano, Data, Função, Número, RegExp, String é um Objeto, mas aprimorada com methods e propriedades específicos para cada tipo. Por exemplo, uma matriz tem uma propriedade de length predefinida, enquanto os objects genéricos não.

 javascript:alert([].length+'\n'+{}.length) 

exibe

 0
 Indefinido

Intrinsecamente, o interpretador FF Gecko também distingue entre Arrays e Objetos genéricos com diferenças distintas que avaliam construções de linguagem.

 javascript: ra=[ "one", "two", "three"]; ra.a=4; ob={0:"one", 1:"two", 2:"three"}; ob.a=4; alert( ra +"\n\n"+ ob +"\n\n"+ ra.toSource() +"\n\n"+ ra.a +"\t .toSource() forgot me! \n\n"+ ra.length +"\t and my length! \n\n"+ ob.toSource()); ps=""; for(i in ra)ps+=i+" "; alert(ps); /* NB .length is missing! */ ps=""; for(i in ob)ps+=i+" "; alert(ps); 

exibindo

 um dois três

 [object object]

 ["um dois três"]

 4 .toSource () me esqueceu! 

 3 e meu comprimento! 

 ({0: "um", 1: "dois", 2: "três", um: 4})

e 0 1 2 a e 0 1 2 a .

Quanto à afirmação de que todos os objects são funções:

Não é syntactically nem semanticamente correto usar uma instância de object arbitrária como uma function como 123() ou "abc"() ou []() ou {}() ou obj() onde obj é qualquer outro tipo de Function , então um object arbitrário INSTANCE não é uma Function . No entanto, dado um object obj e é tipo como Array, Boolean, Date, ... , como obj passou a ser como Array, Boolean, Date, ... ? O que é uma Array, Boolean, Date, ... ?

 javascript: alert([Array, Boolean, Date, Function, Number, Object, RegExp, String] . join('\n\n') ); 

exibe

 function Array() { [native code] } function Boolean() { [native code] } function Date() { [native code] } function Function() { [native code] } function Number() { [native code] } function Object() { [native code] } function RegExp() { [native code] } function String() { [native code] } 

Em todos os casos, sem equívocos, o tipo de object se manifesta como uma definição de function , daí a afirmação de que todos os objects são funções! (A ironia é que eu intencionalmente obscureça e desfoque a distinção de uma instância de object com a de seu tipo! Ainda assim, isso mostra “você não pode ter uma sem a outra”, Objeto e function! A capitalização enfatiza o tipo como oposta à instância.)

Tanto um paradigma funcional quanto um object parecem ser fundamentais para a programação e implementação das primitivas internas de baixo nível do interpretador JS, como Math JSON e true .

  javascript:alert([Math, JSON, true.toSource()].join("\n\n")); 

exibe

 [object Math] [object JSON] (new Boolean(true)) 

Na época do desenvolvimento do Javascript, um estilo de programação centrado em object (estilo OOP’s – Object Oriented Programming – o “‘s” é meu próprio trocadilho!) Estava em voga e o intérprete foi similarmente batizado com Java para dar maior credibilidade . As técnicas de functional programming foram relegadas a exames mais abstratos e esotéricos, estudando as teorias de Autômatos, Funções Recursivas, Linguagens Formais, etc. e, portanto, não tão palatáveis. No entanto, os pontos fortes dessas considerações formais são claramente manifestados no Javascript, particularmente conforme implementado no mecanismo Gecko do FF (ou seja, .toSource() ).


A definição de object para function é particularmente satisfatória, pois é definida como uma relação de recorrência! definido usando sua própria definição!

function Function() { [native code] }
e como uma function é um object, o mesmo sentimento vale para
function Object() { [native code] } .

A maioria das outras definições permanece em um valor terminal estático. No entanto, eval() é um primitivo particularmente poderoso e, portanto, um String também pode incorporar funcionalidades arbitrárias.

Note novamente que o vernáculo usado acima obscurece o tipo de object e a distinção de instâncias.

Uma diferença prática é quando se usa JSON.stringify em uma array todos os índices não numéricos são ignorados:

 var arr = []; var obj = {}; arr['name'] = 'John'; obj['name'] = 'John'; console.log(arr); // will output [name: "John"] console.log(obj); // will output {name: "John"} JSON.stringify(arr); // will return [] JSON.stringify(obj); // will return {"name":"John"} 

A diferença entre as matrizes e os outros objects em JavaScript. Embora as matrizes tenham uma propriedade de comprimento de atualização mágica, para objects que não sejam matrizes, não há como implementar essa propriedade.

 var arrName = []; arrName[5] = "test"; arrName.length; // < - 6 

Array são usados ​​para armazenar coisas com um índice ordinal - use-o como um array tradicional, pilha ou fila. Um object é um hash - use-o para dados que tenham uma chave distinta.

A anotação {} é apenas açúcar sintático para tornar o código mais agradável 😉

JavaScript tem muitos constructos semelhantes, como a construção de funções, onde function () é apenas um sinônimo para

 var Func = new Function("", "");