2012-01-26 29 views
7

Dường như các mảng được tạo với Object.create giống như mảng và quack như mảng, nhưng vẫn không phải mảng thực. Ít nhất với v8/node.js.Mảng Javascript được tạo bằng Object.create - không phải mảng thực?

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

Một số chuyên gia Javascript có thể giải thích lý do vì sao mảng mới tạo của tôi không thể phân biệt được với mảng thực?

Mục tiêu của tôi ở đây là sao chép cấu trúc dữ liệu, bao gồm Mảng có thể có thuộc tính tùy chỉnh được đính kèm. Tôi có thể, tất nhiên, tự đính kèm tài sản cho một Array mới được tạo ra bằng cách sử dụng Object.defineProperty, nhưng có cách nào để làm như vậy bằng cách sử dụng Object.create?

+0

Chúng không thể phân biệt được mục tiêu của bạn. Cách thực hiện đầy đủ khả năng hiện diện - sử dụng 'b = []'; – kirilloid

+0

@kirilloid - đó có thể là một cách tiếp cận hợp lệ đối với một số tình huống nhưng trong trường hợp chức năng của nhà máy thực hiện nội bộ hệ thống ống nước dựa trên prototypeParam, đề xuất của bạn không phải là một tùy chọn. ví dụ. trong việc tạo ra một monoid, bắt đầu với: var monad = Object.create (prototypeParam); Ở đây, nó sẽ thuận tiện nếu prototypeParam có thể là Array.prototype – arcseldon

Trả lời

4

Câu trả lời ngắn gọn là không. This article giải thích tất cả trong một số chi tiết.

+0

Rất rất thú vị! –

+0

Xem http://www.bennadel.com/blog/2292-Extending-JavaScript-Arrays-While-Keeping-Native-Bracket-Notation-Functionality.htm để giải quyết sự cố. – Gili

3

Không, bạn không thể. Object.create là tất cả về nguyên mẫu, nhưng cả hai []Object.create(Array.prototype) được kế thừa từ cùng một đối tượng mẫu thử nghiệm.

gì bạn gọi là "mong muốn hành vi Object.prototype.toString" là nội [[Class]] của đối tượng, đó là không thể thiết lập với Object.create. Tạo "mảng thực" (với lớp Arrayspecial array behaviour - thuộc tính được lập chỉ mục, .length) chỉ có thể sử dụng bằng cách sử dụng array literals hoặc calling the Array constructor.

Các vấn đề liên quan