2015-04-12 15 views
21

Tại sao hai triển khai này hoạt động khác nhau? Chính xác những gì họ đặt ra khi nói đến việc đánh giá nguyên mẫu của họ?Tại sao Object.create() và đối tượng mới() đánh giá các nguyên mẫu khác nhau?

Tạo một đối tượng với nguyên mẫu quy định:

function Foo() {} 

    // creates an object with a specified prototype 
    var bar = Object.create(Foo); 

    console.log(Object.getPrototypeOf(bar)); // returns: function Foo(){} 
    console.log(Foo.isPrototypeOf(bar)); // returns: true 

Tạo một đối tượng với phương thức khởi tạo:

function Foo() {} 

    // creates an object with the constructor method  
    var bar = new Foo(); 

    console.log(Object.getPrototypeOf(bar)); // returns: Foo {} 
    console.log(Foo.isPrototypeOf(bar)); // returns: false 

Ngoài ra, tại sao việc thực hiện thứ hai trả lại cả hai Foo {}false ?

+1

"Ngoài ra, tại sao triển khai thứ hai trả về cả Foo {} và sai?" là một câu hỏi hay. Tôi đã cập nhật câu trả lời của mình để giải quyết nó. – joews

+3

Lưu ý rằng bạn thường làm 'var bar = Object.create (Foo.prototype);', cho bạn biết hành vi mong đợi. – Paulpro

+0

duplicatet có thể có của [Hiểu sự khác biệt giữa 'Object.create()' và 'new SomeFunction()'] (http://stackoverflow.com/q/4166616/1048572) – Bergi

Trả lời

22

Object.create(Foo) có nghĩa là "tạo đối tượng có Foo làm nguyên mẫu".

new Foo() có nghĩa là "Tạo đối tượng có Foo.prototype làm nguyên mẫu và Foo làm hàm tạo".

Do đó Foonguyên mẫu của Bar trong ví dụ đầu tiên và constructor của Bar trong ví dụ thứ hai.

Tôi nghĩ rằng phần thứ hai của câu hỏi của bạn được thúc đẩy bởi sai lệch điều khiển đầu ra - Object.getPrototypeOf(bar) thực sự trả Foo.prototype, không Foo:

function Foo() {} 
var bar = new Foo(); 

Object.getPrototypeOf(bar) === Foo 
// -> false 

Object.getPrototypeOf(bar) === Foo.prototype 
// -> true 
+0

Cảm ơn bạn đã trả lời rõ ràng! – shmuli

11

Khi bạn sử dụng từ khoá 'mới' để tạo một đối tượng JavaScript thực sự làm tăng trong hai dòng mã cho đối tượng của bạn.

Nếu bạn có ý định tạo ra một đối tượng với instantiation pseudoclassical bạn tạo đối tượng của bạn như thế này:

var Foo = function() { 
this.property = 'baz'; 
}; 

Khi bạn gọi var bar = new Foo() Javascript chạy Foo như sau:

var Foo = function() { 
// ADDED CODE: var this = Object.create(Foo.prototype); 
this.property = 'baz'; 
// ADDED CODE: return this; 

Sử dụng Object.create tạo mối quan hệ ủy nhiệm từ đối tượng mới được tạo cho đối tượng được chỉ định, vì vậy trong thanh trường hợp đầu tiên của bạn là ủy nhiệm tra cứu của nó cho Foo, nhưng trong trường hợp thứ hai, các tra cứu được ủy nhiệm cho Foo.prototype.

Bạn có thể tìm thấy this bài đăng trên blog thú vị. Nó đi vào sự diễn giải giả tạo (sử dụng từ khóa mới) như trái với Prototypal instantiation, không sử dụng từ khóa mới.

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