2012-03-31 31 views
29

Las matrices tienen una propiedad de "longitud" por defecto.Agregar propiedad a la matriz de Javascript

¿Puedo agregarles propiedades personalizadas?

Sin tener que hacerles objetos

+2

¿qué quiere decir con * "agregar propiedades personalizadas sin tener que hacer que se conviertan en objetos?" * Arrays ARE objetos. Casi todo en JS es un objeto. ¿Y cuáles son estas propiedades? ¿Puedes explicar más? – Joseph

+0

Ellos ** son ** objetos. Solo un tipo especial de objetos.Como las funciones, por ejemplo, que también son un tipo especial de objetos. – ThiefMaster

+0

Consulte también [esta pregunta relacionada] (http://stackoverflow.com/questions/24730145/what-are-the-drawbacks-of-setting-string-properties-on-arrays) para saber por qué no debe hacer esto. –

Respuesta

37

Sure.

var arr = [1,2,3,4,5]; 
arr.prop = 'value'; 

matrices son ya objetos en JavaScript - que sólo tienen algunas características adicionales y una sintaxis literal especial.

+0

¿mi propiedad se repetirá con el resto de los elementos? porque en console.log no lo veo con texto opaco como "longitud" – ellabeauty

+5

Se iterarán cuando uses 'for (var key in arr)'. Pero eso es algo que no deberías usar en matrices de todos modos, por lo que no debería ser un problema para ti. Una iteración 'for (var i = 0; i ThiefMaster

+0

si usa un bucle 'for in', la propiedad será iterado. En un ciclo 'for' regular, no lo será, ya que solo accederá a cada miembro por su índice de matriz. Tampoco será iterado por los métodos de matriz nativa ES5 como 'forEach'. –

2

Sí. Puede agregarlos al objeto con sólo declarar ellos y también se puede extender matriz mediante Array.prototype

var j = new Array(); 
j.yourprop = "foo"; 
+4

' var j = []; 'es más agradable. – ThiefMaster

+3

Sí, acepto que mi camino apesta –

+11

Prefiero 'var j = (función (array) {return new array();} (window.Array))' –

22

Como estado otras respuestas, es perfectamente posible, porque las matrices de JavaScript son sólo objetos. Sin embargo, todavía existe la pregunta de si es una buena idea o no.

Esa es una pregunta de "estilo de codificación", por lo que es difícil decirlo objetivamente, pero Douglas Crockford no tiene ningún problema (al menos en algunos casos). En JavaScript: The Good Parts, en realidad usa el ejemplo de agregar un método "total" a una matriz.

Debido a que una matriz es realmente un objeto, podemos añadir métodos directamente a un array individuales:

// Give the data array a total function 

data.total = function() { 
    return this.reduce(add, 0); 
}; 

total = data.total(); // total is 108 

Desde la cadena 'total' no es un entero, añadiendo una propiedad total a una matriz no cambia su longitud

(p62, "javascript las partes buenas" de Crockford, que se encuentran en Google Books)

Sin embargo, vale la pena mencionar que estas propiedades adicionales no están incluidos en la serialización JSON, y serían desechados si lo hace cualquier cosa como arr = arr.slice(1);.

+0

Gracias por incluir referencias. –

+0

Además, si la matriz pasa por cualquiera de sus métodos prototipo (mapa, filtro, etc.) la propiedad no se transferirá a la nueva matriz, ya que el método se puso en una instancia de 'Array'. Probablemente esperado, pero tal vez no deseable en este caso? –

1

¿Si pretendía ocultarlo en una matriz, etc.? [por lo menos eso es lo que estaba buscando.]

Object.defineProperty(targ, "myVal", { enumerable: false, writable: true }); 

A continuación, la matriz no lo agrega a la longitud así que no es una propiedad de un valor que supongo que se podría decir.

Luego, si desea ver las claves en un objeto, por ejemplo, Object.keys no lo verá, pero Reflect.ownKeys lo hará.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys

el reflejo versión de defineProperty devolverá el éxito o el fracaso, mientras que los retornos del objeto del objeto pasado.

Recuerda preventExtensions (como dice) evita que tú u otras personas puedan extenderlas. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions

Cuestiones relacionadas