2012-01-31 35 views
21

Tôi vừa mới bắt đầu đọc lên trên OOP javascript và một điều mà tác giả dường như bỏ qua là khi một đối tượng A đã được công bố và đột nhiên tôi thấy "A.prototype.constructor = A; Ví dụ,Tại sao sử dụng object.prototype.constructor trong OOP javascript?

var A = function(){}; // This is the constructor of "A" 
A.prototype.constructor = A; 
A.prototype.value = 1; 
A.prototype.test = function() { alert(this.value); } 
var a = new A(); // create an instance of A 
alert(a.value); // => 1 

Vì vậy, tôi chạy lệnh trong firebug "var A = function() {};" và sau đó "A.Constructor" cho thấy đó là một chức năng.Tôi hiểu điều này.
Tôi chạy mã "A.prototype. constructor = A; "và tôi nghĩ điều này thay đổi hàm tạo A từ Hàm thành A.

Thuộc tính hàm tạo của A đã là chan ged phải không? Thay vào đó khi tôi chạy "A.constructor" nó mang lại cho tôi hàm().

Vấn đề là gì?

Tôi cũng thấy A.constructor.prototype.constructor.prototype .. điều gì đang xảy ra?

+6

Những tác giả, ở đâu? –

+0

Mã tôi nhận được từ đây là http://www.ruzee.com/blog/2008/12/javascript-inheritance-via-prototypes-and-closures – Matt

Trả lời

12

Nếu A kế thừa B sử dụng A.prototype = new B();, bạn cần phải thiết lập lại các tài sản constructor cho lớp Một sử dụng A.prototype.constructor=A;, nếu trường hợp của A sẽ có một constructor của B.

Trong trường hợp của bạn, A.prototype.constructor === A sẽ trở thành sự thật, vì vậy A.prototype.constructor = A không làm gì cả.

+0

Thú vị nên A.prototype.constructor = A; sẽ làm cho A cô lập từ B? Bằng cách này, bạn có thể mở rộng thêm các thuộc tính bằng cách sử dụng A.prototype mà không cần thêm các thuộc tính khác vào B? – Matt

+0

Không có gì về cách ly, nó chỉ đảm bảo A có thuộc tính hàm tạo đúng. – xdazz

+11

Mục đích của việc có thuộc tính hàm tạo đúng là gì? Khi nào thì A.prototype.constructor có thực sự được tư vấn trong thực tế? Nó dường như không ảnh hưởng đến hành vi tạo ra các phiên bản mới của A, afaics. Câu trả lời phải rõ ràng đến mức nói chung là không được nói ra, đó là lý do tại sao nó đã lảng tránh tôi :-) – Yetanotherjosh

4

Bạn có thể nhanh chóng kiểm tra ra rằng giao bổ sung làm hoàn toàn không có gì:

var A = function() {}; 
A.prototype.constructor === A; // true -- why assign then? 

Reset tài sản constructor chỉ có ý nghĩa nếu bạn đã gán một đối tượng nguyên mẫu mới đến lớp, ghi đè các nhà xây dựng ban đầu:

var A = function() {}; 
A.prototype = protoObject; // some object with members that you'd like to inherit 
A.prototype.constructor = A; // reset constructor 

Trong trường hợp của bạn, tác giả có thể mù quáng làm điều này là thực hành tốt, ngay cả trong trường hợp không cần thiết.

2

Mã này nếu thường xuyên sử dụng trong mô hình thừa kế cổ điển JS (mã là từ Patterns JavaScript bằng cách Stoyan Stefanov):

function inherit(C, P) { 
    var F = function() {}; 
    F.prototype = P.prototype; 
    C.prototype = new F(); 
    C.uber = P.prototype; 
    C.prototype.constructor = C; 
} 

gán constructor quyền lớp trẻ.

Trong trường hợp của bạn, không có gì, kể từ A.prototype.constructor === A trước khi chuyển nhượng.

1

Bạn có thể muốn xem câu trả lời của tôi cho câu hỏi tương tự:

https://stackoverflow.com/a/19616652/207661

TL; DR: constructor không phải là một tài sản riêng của một ví dụ. Vì vậy, để làm cho mọi thứ trông phù hợp, trình thông dịch JavaScript cần phải thiết lập prototype.constructor để tự hoạt động. Tính năng này có thể được sử dụng trong các chức năng hoạt động chung trên nhiều loại đối tượng khác nhau.

1

Theo MDN, tất cả các đối tượng thừa kế một tài sản constructor từ nguyên mẫu của họ:

Example 1: 
var o = {}; 
o.constructor === Object; // true 

..

Example2: 
function Tree() { 
}  
var theTree = new Tree(); 
console.log(theTree.constructor === Tree); // true 

Khi chạy, nó không tạo ra bất kỳ sự khác biệt nào dựa trên giá trị của thuộc tính hàm tạo. Tuy nhiên, vì thuộc tính hàm tạo trả về một tham chiếu đến hàm Object đã tạo ra mẫu của cá thể, nên nên đặt lại thuộc tính của hàm tạo khi chúng gán một mẫu mới cho hàm Object (Các đối tượng).

var Forest = function() {}; 
Forest.prototype = theTree; 
console.log(new Forest().constructor === Tree); // true 
Forest.prototype.constructor = Forest; 
console.log(new Forest().constructor === Forest); // true 

https://jsfiddle.net/j1ub9sap/

Để biết chi tiết: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor

+0

Xin chào, tôi nhảy vào nhận xét của bạn vài tháng sau vì tôi không hiểu câu này: "Tuy nhiên, vì thuộc tính hàm tạo trả về tham chiếu đến hàm Object đã tạo mẫu thử của cá thể " Hàm Object không tạo mẫu thử nghiệm của cá thể, nó tạo ra cá thể trực tiếp không? Điều đó có chính xác ? Cảm ơn – jobou

+0

Điều đó có nghĩa là nếu rừng kế thừa theTree sử dụng Forest.prototype = new theTree(), các thể hiện của Forest sẽ có một hàm tạo của theTree. Để có Forest là một nhà xây dựng, người ta cần thiết lập lại thuộc tính constructor cho Forest bằng Forest.prototype.constructor = Forest. –

+0

Tôi hiểu ví dụ của bạn. Câu hỏi của tôi là nhiều hơn về tài liệu chính thức: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor Nó nói "Trả về một tham chiếu đến hàm Object đã tạo ra cá thể nguyên mẫu. Tuy nhiên tất cả các ví dụ trong trang này không có nguyên mẫu của họ overriden. Không có thừa kế tùy chỉnh: 'var a = []; a.constructor === Array; 'Vậy tại sao nó không nói rằng" hàm tạo là tham chiếu đến hàm Object đã tạo ra cá thể đó "? Cảm ơn – jobou

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