2012-01-26 21 views
7

Parece que las matrices creadas con Object.create caminan como matrices y graban como matrices, pero todavía no son matrices reales. Al menos con v8/node.js.Arrays Javascript creados con Object.create - Arrays no reales?

> a = [] 
[] 
> b = Object.create(Array.prototype) 
{} 
> a.constructor 
[Function: Array] 
> b.constructor 
[Function: Array] 
> a.__proto__ 
[] 
> b.__proto__ 
[] 
> a instanceof Array 
true 
> b instanceof Array 
true 
> Object.prototype.toString.call(a) 
'[object Array]' 
> Object.prototype.toString.call(b) 
'[object Object]' 

¿Puede algún gurú Javascript explicar por qué es así, y cómo hacer para que mi matriz recién creada es indistinguible de una matriz real?

Mi objetivo aquí es clonar las estructuras de datos, incluidas las matrices que pueden tener propiedades personalizadas adjuntas. Podría, por supuesto, adjuntar manualmente propiedades a una matriz recién creada usando Object.defineProperty, pero ¿hay alguna manera de hacerlo usando Object.create?

+0

Son bastante indistinguibles para su objetivo. Cómo hacer totalmente indistinguible - use 'b = []'; – kirilloid

+0

@kirilloid: ese podría ser un enfoque válido para algunas situaciones, pero en situaciones en las que una función de fábrica internamente realiza la instalación de tuberías basada en un prototipoParam, su sugerencia no es una opción. p.ej. en la creación de un monoide, comience con: var mónada = Object.create (prototypeParam); Aquí, sería conveniente si prototypeParam podría ser Array.prototype – arcseldon

Respuesta

4

La respuesta corta es no. This article lo explica todo con cierto detalle.

+0

¡Muy, muy interesante! –

+0

Consulte http://www.bennadel.com/blog/2292-Extending-JavaScript-Arrays-While- Keeping-Native-Bracket-Notation-Functionality.htm para obtener una solución alternativa. – Gili

3

No, no puedes. Object.create es todo sobre prototipos, pero tanto [] como Object.create(Array.prototype) heredan del mismo objeto prototipo.

Lo que llamas "comportamiento Object.toString deseada" es el [[Class]] interna del objeto, que es imposible establecer con Object.create. La creación de "matrices verdaderas" (con una clase Array y special array behaviour - propiedades indexadas, .length) solo es posible utilizando array literals o calling the Array constructor.