¿Por qué puedo agregar propiedades con nombre a una matriz como si fuera un objeto?

Los siguientes dos fragmentos de código diferentes me parecen equivalentes:

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

y

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

porque ambos se comportan igual, y también typeof(myArray) == typeof(myObjects) (ambos dan ‘object’).

¿Hay alguna diferencia entre estas variantes?

Prácticamente todo en javascript es un objeto, por lo que puede “abusar” de un objeto Array estableciendo propiedades arbitrarias en él. Esto debería ser considerado dañino sin embargo. Las matrices son para datos indexados numéricamente; para las claves no numéricas, use un Objeto.

Aquí hay un ejemplo más concreto de por qué las teclas no numéricas no “encajan” en una matriz:

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

Esto no mostrará ‘2’, sino ‘0’: de hecho, no se han agregado elementos a la matriz, solo se agregaron algunas propiedades nuevas al objeto de la matriz.

En JS, las matrices son objetos, ligeramente modificados (con algunas funciones más).

Funciones como:

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

Todo en JavaScript es un objeto además de los tipos primitivos.

El código

 var myArray = Array(); 

crea una instancia del objeto Array mientras

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

crea una instancia de objeto Objeto.

Pruebe el siguiente código

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

Entonces verá que la diferencia está en el tipo de constructor de objetos.

La instancia del objeto Array contendrá todas las propiedades y métodos del prototipo Array.

Yo pienso, yo también metafórico y críptico con la respuesta anterior. Aclaración sigue

Una instancia de Array, Boolean, Date, Function, Number, RegExp, String es un Objeto pero mejorado con métodos y propiedades específicas para cada tipo. Por ejemplo, una matriz tiene una propiedad de length predefinida, mientras que los objetos generics no.

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

muestra

 0
 indefinido

Intrínsecamente, el intérprete de Gecko de FF también distingue entre Arrays y Objetos generics con distintas diferencias que evalúan construcciones de lenguaje.

 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); 

mostrando

 uno dos tres

 [objeto Objeto]

 ["uno dos tres"]

 4 .toSource () me olvidó 

 3 y mi longitud! 

 ({0: "uno", 1: "dos", 2: "tres", a: 4})

y 0 1 2 a y 0 1 2 a .

En cuanto a la afirmación de que todos los objetos son funciones:

No es ni sintáctica ni semánticamente correcto usar una instancia de objeto arbitraria como una función como 123() o "abc"() o []() o {}() u obj() donde obj es cualquier otro tipo de Function , por lo que un objeto arbitrario INSTANCE no es una Function . Sin embargo, dado un objeto obj y su tipo es Array, Boolean, Date, ... , ¿cómo llegó obj a ser Array, Boolean, Date, ... ? ¿Qué es un Array, Boolean, Date, ... ?

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

muestra

 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] } 

En todos los casos, sin equívoco, el tipo de objeto se manifiesta como una definición de function , de ahí la afirmación de que todos los objetos son funciones. (¡La ironía es que intencionalmente oscurecí y borré la distinción de una instancia de objeto con la de su tipo! Aún así, esto muestra “no se puede tener una sin la otra”, ¡Objeto y función! La mayúscula enfatiza el tipo como opuesto a la instancia.)

Tanto un paradigma funcional como un paradigma de objeto parecen ser fundamentales para la progtwigción y la implementación de las primitivas incorporadas de bajo nivel del intérprete JS, como Math y JSON y true .

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

muestra

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

En el momento del desarrollo de Javascript, un estilo de progtwigción centrado en objetos (OOP’s – estilo de progtwigción orientado a objetos – el “s” es mi propio juego de palabras!) Estaba en boga y el intérprete fue bautizado de manera similar con Java para darle mayor credibilidad . Las técnicas de progtwigción funcional fueron relegadas a exámenes más abstractos y esotéricos que estudian las teorías de Autómatas, Funciones Recursivas, Lenguajes Formales, etc. y como tales no son tan apetecibles. Sin embargo, las fortalezas de estas consideraciones formales se manifiestan claramente en Javascript, particularmente cuando se implementan en el motor Gecko de FF (es decir, .toSource() ).


La definición de Objeto para Función es particularmente satisfactoria ya que se define como una relación de recurrencia. ¡definido usando su propia definición!

function Function() { [native code] }
y dado que una función es un Objeto, el mismo sentimiento es válido para
function Object() { [native code] } .

La mayoría de las otras definiciones quedan inactivas a un valor terminal estático. Sin embargo, eval() es una primitiva particularmente poderosa, por lo que una cadena también puede incorporar funcionalidad arbitraria.

Tenga en cuenta una vez más, la lengua vernácula utilizada anteriormente oscurece el tipo de objeto y la distinción de instancia.

Una diferencia práctica es cuando se utiliza JSON.stringify en una array todos los índices no numéricos se ignoran:

 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"} 

La diferencia entre las matrices y los otros objetos en JavaScript. Si bien las matrices tienen una propiedad de longitud que se actualiza mágicamente, para los objetos que no sean las matrices, no hay forma de implementar dicha propiedad.

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

Array se usa para almacenar cosas con un índice ordinal: úselo como una matriz, stack o cola tradicional. Un objeto es un hash: úselo para datos que tengan una clave distinta.

La {} -notación es solo azúcar sintáctica para hacer que el código sea más agradable 😉

JavaScript tiene muchas construcciones similares, como la construcción de funciones, donde function () es solo un sinónimo de

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