2009-05-17 24 views
87

Los siguientes dos fragmentos de código diferentes parecen equivalentes a mí:¿Cuál es la diferencia entre una matriz y un objeto?

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

y

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

, ya que ambos se comportan de la misma, y ​​también typeof(myArray) == typeof(myObjects) (tanto el rendimiento como 'objeto').

¿Hay alguna diferencia entre estas variantes?

Respuesta

107

Prácticamente todo en JavaScript es un objeto, para que pueda "abuso" un objeto Array estableciendo las propiedades arbitrarias en él. Esto should be considered harmful 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 qué teclas no numéricas no "encajan" un Array:

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

alert(myArray.length); 

Esto no mostrará '2', pero '0' - efectivamente, no hay elementos han sido agregado a la matriz, solo algunas propiedades nuevas agregadas al objeto de la matriz.

+2

myArray.length devuelve un índice numérico/clave del último elemento de la matriz, pero no el número real de elementos. ¿Las propiedades del objeto Array no son lo mismo que los valores de matriz? –

+1

Solo intentaba ilustrar la semántica pretendida del objeto Array si se trata de un objeto normal. El artículo vinculado hace un mejor trabajo :) –

+5

La próxima vez que alguien diga que JavaScript es un buen lenguaje para desarrollar, le mostraré esta muestra. Gracias. –

-1

El {} -notation es simplemente azúcar sintáctico para hacer el código más bonito ;-)

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

var Func = new Function("<params>", "<code>"); 
+3

función constructora es ** ** NO sinónimo de la función literal. El literal tiene un alcance léxico mientras que el constructor es global. '{}' es una notación de objeto literal, '[]' es una matriz literal, no estoy seguro de cuál es el objetivo de tu respuesta. –

+0

Además, las funciones declaradas están disponibles antes de ejecutar cualquier código, las asignaciones que utilizan el constructor de Funciones no están disponibles hasta que se ejecuta el código que las crea. – RobG

13

En matrices JS son objetos, apenas 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 
+0

Aunque no creo que todas las funciones enumeradas estén incorporadas en cada implementación de JS, usted entendió el punto. La otra diferencia sería un prototipo diferente (que está implicado por esas funciones adicionales). – Rashack

5

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

El código

var myArray = Array(); 

crea una instancia del objeto de matriz mientras

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

crea una instancia de objeto del objeto.

Prueba el siguiente código

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

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

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

4

Me piensa, 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 se ha mejorado con métodos y propiedades específicos para cada tipo. Por ejemplo, una matriz tiene una propiedad predefinida length, mientras que los genéricos no.

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

pantallas

 
0 
undefined 

Intrínsecamente, el intérprete FF Gecko también distingue entre matrices y genéricos Los objetos con distintas diferencias que evalúan las construcciones del 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

 
one,two,three 

[object Object] 

["one", "two", "three"] 

4 .toSource() forgot me! 

3 and my length! 

({0:"one", 1:"two", 2:"three", 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ácticamente ni semánticamente correcta de utilizar una instancia de objeto arbitrario como una función como 123() o "abc"() o []() o {}() o obj() donde obj es cualquier tipo distinto de Function, por lo que un objeto arbitrario INSTANCE no es 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')); 

pantallas

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ívocos, el tipo de objeto se manifiesta como una definición function, por lo tanto, 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 se opusieron a la instancia.)

Tanto un paradigma funcional y el objeto parece ser fundamental para la programación y ejecución de las primitivas incorporadas JS intérprete de bajo nivel, tales como Math y JSON y true.

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

pantallas

[object Math] 

[object JSON] 

(new Boolean(true)) 

En el momento de la elaboración de Javascript, un estilo de programación centrada en el objeto (de la POO - Orientado a Objetos estilo de programación - 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 programació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 del objeto para la 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 puesto que una función es un objeto del mismo sentimiento se mantiene para
function Object() { [native code] }.

La mayoría de las otras definiciones son inactivas a un valor de terminal estático. Sin embargo, eval() es una primitiva particularmente potente y, por lo tanto, una cadena también puede incorporar funciones arbitrarias.

Nota nuevamente, la vernácula utilizada anteriormente oscurece el tipo de objeto y la distinción de instancia.

1

Una diferencia práctica es cuando se usa en una JSON.stringifyarray todos no numérico índices son 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"} 
Cuestiones relacionadas