2012-01-26 13 views
7

Wygląda na to, że tablice utworzone za pomocą Object.create chodzą jak tablice i działają jak tablice, ale nadal nie są prawdziwymi tablicami. Przynajmniej z v8/node.js.Tablice JavaScript utworzone za pomocą Object.create - nie prawdziwe tablice?

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

Może jakiś guru JavaScript wyjaśnić, dlaczego tak jest, i jak zrobić to tak, że mój nowo utworzona tablica jest nie do odróżnienia od prawdziwej tablicy?

Moim celem jest klonowanie struktur danych, w tym tablic, które mogą mieć załączone właściwości niestandardowe. Mógłbym, oczywiście, ręcznie dołączyć właściwości do nowo utworzonego macierzy przy użyciu Object.defineProperty, ale czy istnieje sposób, aby to zrobić, używając Object.create?

+0

Są raczej nie do odróżnienia od celu. Jak dokonać pełnego niedopasowania - użyj 'b = []'; – kirilloid

+0

@kirilloid - to może być poprawne podejście w niektórych sytuacjach, ale w sytuacjach, gdy mówimy, że funkcja fabryczna wewnętrznie wykonuje instalację hydrauliczną opartą na prototypie Param, twoja sugestia nie jest opcją. na przykład. w tworzeniu monoidu, zacznij od: var monad = Object.create (prototypeParam); Tutaj byłoby wygodnie, gdyby prototypParam mógł być Array.prototype – arcseldon

Odpowiedz

4

Krótka odpowiedź brzmi: nie. This article wyjaśnia to wszystko w kilku szczegółach.

+0

Bardzo, bardzo interesujące! –

+0

Zobacz http://www.bennadel.com/blog/2292-Extending-JavaScript-Arrays-While-Keeping-Native-Bracket-Notation-Functionality.htm, aby obejść ten problem. – Gili

3

Nie, nie możesz. Object.create to prototypy, ale zarówno [] jak i Object.create(Array.prototype) dziedziczą z tego samego obiektu prototypowego.

co nazywasz „pożądane zachowanie Object.prototype.toString” jest wewnętrznym [[Class]] obiektu, co jest niemożliwe do skonfigurowania z Object.create. Tworzenie "prawdziwych tablic" (z klasą Array i special array behaviour - indeksowanych właściwości, .length) jest możliwe tylko przy użyciu array literals lub calling the Array constructor.