7

Tôi đã đọc trên javascript vườn http://bonsaiden.github.com/JavaScript-Garden/ về nguyên mẫu trong javascript và một trong những ví dụ của nó đi như thế này:tại sao danh sách các nhà xây dựng thực tế của một lớp trong javascript quan trọng

function Foo() { 
    this.value = 42; 
} 
Foo.prototype = { 
    method: function() {} 
}; 

function Bar() {} 

// Set Bar's prototype to a new instance of Foo 
Bar.prototype = new Foo(); 
Bar.prototype.foo = 'Hello World'; 

// Make sure to list Bar as the actual constructor <------------------- 
Bar.prototype.constructor = Bar; 

Thông báo dòng mà đọc Hãy chắc chắn để list Bar là hàm tạo thực tế. Tôi thực sự bị mất về những gì điều này không/là. Tôi đã thử tạo các phiên bản mới của Bar() có và không có dòng cuối cùng. Nhưng gọi "giá trị" hoặc "phương pháp" trên những trường hợp đó trả về cùng một thứ chính xác. Vì vậy, tôi tự hỏi, những gì là cần thiết (tôi giả sử phải có một) xác định các nhà xây dựng?

Cảm ơn bạn !!!

Trả lời

6

Mỗi chức năng có một tài sản, nó được gán khi đối tượng chức năng được tạo ra, nó trỏ prototype đến một đối tượng mới được tạo ra mà được thừa hưởng từ Object.prototype, và nó có một tài sản constructor, mà chỉ đơn giản chỉ trở lại với chức năng riêng của mình.

Mục đích của thuộc tính prototype là cung cấp cách thức để thực hiện kế thừa, sử dụng hàm dựng. Khi bạn gọi một hàm với toán tử new, nó sẽ tạo một đối tượng mới kế thừa từ hàm xây dựng prototype của hàm dựng đó.

Bây giờ, mục đích của constructor bất động sản là phải có một cách để xem lại các nhà xây dựng đã tạo ra một đối tượng, ví dụ:

function Foo() {} 
// default value of the property: 
Foo.prototype.constructor == Foo; // true 

Khách sạn này được thừa hưởng bởi "trường hợp" của Foo , vì vậy bạn có thể biết được nhà xây dựng đã được sử dụng để tạo ra một đối tượng:

var foo = new Foo(); 
foo.constructor == Foo; 

Nếu bạn gán một đối tượng mới để nguyên mẫu của chức năng, mối quan hệ này bị mất:

function Bar() {} 
Bar.prototype = { inherited: 1 }; 

Bar.prototype.constructor == Bar; // false 
Bar.prototype.constructor == Object; // true 

Và nó cũng ảnh hưởng đến các trường hợp của hàm:

var bar = new Bar(); 
bar.constructor == Bar; // false 
bar.constructor == Object; // true 

Một trường hợp tương tự là khi bạn có hai hay nhiều mức độ thừa kế sử dụng nhà thầu, cách phổ biến nhất được sử dụng để biểu thị mối quan hệ thừa kế giữa các hàm, là gán thuộc tính prototype của cấp thứ hai, ví dụ:

function Parent() {} 

function Child() {} 
Child.prototype = new Parent(); 

Đoạn mã trên có một số vấn đề, đầu tiên, nó thực thi logic của các nhà xây dựng cha mẹ để tạo ra các mối quan hệ thừa kế, nhưng đó là một câu chuyện khác, trong ví dụ trên là tài sản constructor cũng bị ảnh hưởng, vì chúng ta thay thế hoàn toàn Child.prototype đối tượng:

var child = new Child(); 
child.constructor == Parent; // true 

Nếu chúng ta thay thế thay thế các giá trị của các tài sản của constructorChild.prototype sau khi gán cho nó, nó sẽ hiển thị các hành vi mong đợi:

function Child() {} 
Child.prototype = new Parent(); 
Child.prototype.constructor = Child; 

var child = new Child(); 
child.constructor == Child; // true 
+0

Cảm ơn lời giải thích chi tiết như vậy. Tất cả đều có lý. Điều duy nhất vẫn còn lỗi tôi nhưng tôi có thể bỏ qua là nó trông một chút thông tư trong Child.prototype.constructor = Trẻ em –

+1

@Nik, Bạn đang chào đón! Vâng, nó thực sự tròn theo thiết kế, ví dụ: 'Object.prototype.constructor.prototype.constructor.prototype.constructor == Object;' ;-) – CMS

2

Tôi tin rằng điều này liên quan đến việc khởi tạo Thanh bằng từ khóa mới. Tôi tin rằng bằng cách sử dụng mới sẽ tìm Bar.prototype.constructor. Trước dòng đó đối tượng được liên kết với Bar.prototype.contructor là kiểu Foo nên khi được instantiated mà không có dòng đó, nó sẽ tạo một đối tượng Foo thay vì đối tượng Bar.

+0

Cảm ơn Keith! ; Đó là một lời giải thích ngắn gọn và cho điểm cũng như –

+1

Bạn được chào đón! Nếu điều này đã giúp bạn, bạn có thể +1 nó? –

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