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

Resuelto prinzdezibel asked hace 15 años • 8 respuestas

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 además typeof(myArray) == typeof(myObjects)(ambos producen 'objeto').

¿Hay alguna diferencia entre estas variantes?

prinzdezibel avatar May 17 '09 16:05 prinzdezibel
Aceptado

Prácticamente todo en javascript es un objeto, por lo que puedes "abusar" de un objeto Array estableciendo propiedades arbitrarias en él. Sin embargo , esto debería considerarse perjudicial . Las matrices son para datos indexados numéricamente; para claves no numéricas, use un Objeto.

Aquí hay un ejemplo más concreto de por qué las claves 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'; efectivamente, no se han agregado elementos a la matriz, solo algunas propiedades nuevas agregadas al objeto de la matriz.

Paul Dixon avatar May 17 '2009 09:05 Paul Dixon

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 
Casey avatar May 17 '2009 09:05 Casey

Pienso yo demasiado metafórico y críptico con la respuesta anterior. Sigue una aclaración.

Una instancia de Matriz, Booleano, Fecha, Función, Número, RegExp, Cadena es un Objeto pero mejorado con métodos y propiedades específicas de cada tipo. Por ejemplo, una matriz tiene una lengthpropiedad predefinida, mientras que los objetos genéricos no.

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

muestra

0
indefinido

Intrínsecamente, el intérprete de FF Gecko también distingue entre matrices y objetos genéricos con distintas diferencias al evaluar 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

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 ay 0 1 2 a.

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

No es sintáctica ni semánticamente correcto utilizar una instancia de objeto arbitrario como una función como 123()o "abc"()o []()o {}()donde obj()es objde cualquier tipo distinto de Function, por lo que una INSTANCIA de objeto arbitrario no es un Function. Sin embargo, dado un objeto objy su tipo como Array, Boolean, Date, ..., ¿cómo llegó obja serlo Array, Boolean, Date, ...? Que 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 lugar a dudas, el tipo de objeto se manifiesta como una functiondefinición, ¡de ahí la afirmación de que todos los objetos son funciones! (¡Lo irónico es que intencionalmente oscurecí y desdibujé la distinción de una instancia de objeto con la de su tipo! Aún así, esto muestra "no puedes tener uno sin el otro", ¡Objeto y Función! Las mayúsculas enfatizan el tipo como opuesto a instancia.)

Tanto el paradigma funcional como el de objetos parecen ser fundamentales para la programación e implementación de las primitivas integradas de bajo nivel del intérprete JS, como Mathy JSONy 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, estaba de moda un estilo de programación centrado en objetos (OOP's - estilo de programación orientada a objetos - ¡la "'s" es mi propio juego de palabras!) y el intérprete fue bautizado de manera similar con Java para darle mayor credibilidad. . Las técnicas de programación funcional quedaron relegadas a exámenes más abstractos y esotéricos que estudiaban las teorías de autómatas, funciones recursivas, lenguajes formales, etc. y, como tales, no eran aceptables. Sin embargo, los puntos fuertes de estas consideraciones formales se manifiestan claramente en Javascript, particularmente tal como se implementa en el motor Gecko de FF (es decir, .toSource()).


¡La definición de Objeto para Función es particularmente satisfactoria porque 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 se aplica a
function Object() { [native code] }.

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

Tenga en cuenta nuevamente que la lengua vernácula utilizada anteriormente oscurece la distinción entre el tipo de objeto y la instancia.

Ekim avatar May 17 '2011 20:05 Ekim

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 del objeto Objeto.

Pruebe el siguiente código

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

Entonces verás 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.

Dasha Salo avatar May 17 '2009 09:05 Dasha Salo