2012-11-02 38 views
6

Tôi đang làm việc trên một dự án JavaScript sử dụng Thừa kế nguyên mẫu. Cách tôi quyết định sử dụng nó như sau:Nguyên mẫu Trình tạo cuộc gọi thừa kế hai lần

var MySuperClass = function (param) { 
    this.prop = param; 
}; 
MySuperClass.prototype.myFunc = function() { 
    console.log(this.prop); 
}; 

var MySubClass = function (param) { 
    MySuperClass.call(this, param); 
}; 
MySubClass.prototype = new MySuperClass(); 
MySubClass.prototype.constructor = MySubClass; 

var obj = new MySubClass('value'); 
obj.myFunc(); 

Với sự nhấn mạnh vào thừa kế. Vấn đề với điều này là nếu tôi đặt một console.log trong hàm tạo của mỗi lớp (siêu và phụ), lớp siêu được gọi hai lần, một khi nó được chuyển vào lớp con với MySubClass.prototype = new MySuperClass(); mà không cần bất kỳ các tham số và một lần với các tham số khi nó là 'constructor stolen' trong constructor của lớp con.

Điều này có thể gây ra lỗi nếu sau đó tôi cố lưu các thông số đó (nghĩa là tôi phải thêm logic để xử lý các tham số trống).

Bây giờ nếu tôi làm điều này:

var MySubClass = function (param) { 
    MySuperClass.call(this, param); 
}; 
MySubClass.prototype = MySuperClass; 
MySubClass.prototype.constructor = MySubClass; 

Tất cả mọi thứ dường như làm việc một cách chính xác nhưng tôi chưa bao giờ thấy bất cứ ai làm điều này trước (trong Googl'ing của tôi).

Bất cứ ai có thể giải thích cho tôi nếu và cách thứ hai không chính xác (có vẻ như tương tự như hàm kế thừa Crockford) và cách sửa lỗi thứ nhất để không kích hoạt hai lần nếu được?

+0

Bản sao có thể có của [Lý do * (không) * để sử dụng từ khóa 'mới' ở đây là gì?] (Http://stackoverflow.com/questions/12592913/what-is-the-reason-to-use -the-new-keyword-here) – Bergi

Trả lời

7

Việc làm này không phải là một giải pháp đúng:

MySubClass.prototype = MySuperClass; 

Bạn đang thiết lập các chức năng chính nó như là nguyên mẫu thay vì đối tượng nguyên mẫu, vì vậy bạn không kế thừa những gì bạn mong muốn.


Nhưng bạn nói đúng. Làm điều này không gọi hàm tạo, có thể gây ra vấn đề.

MySubClass.prototype = new MySuperClass(); 

Các giải pháp là sử dụng Object.create để thiết lập các thừa kế. Nó cung cấp cho bạn một đối tượng mới kế thừa từ đối tượng được cung cấp, nhưng không gọi bất kỳ hàm tạo nào.

MySubClass.prototype = Object.create(MySuperClass.prototype); 

Bây giờ bạn có một đối tượng giao cho MySubClass.prototype được thừa kế từ MySuperClass.prototype, nhưng bạn không bao giờ phải thực sự gọi các nhà xây dựng.


Non ES5 triển khai phù hợp sẽ không hỗ trợ Object.create, nhưng bạn có thể làm cho một (một phần) shim cho nó.

Một lần nữa, đây không phải là toàn bộ, nhưng nó mô phỏng đủ để có thể tạo các đối tượng kế thừa mà không phải gọi hàm tạo tham chiếu đối tượng mẫu.

+0

Thankyou rất nhiều :) – obie

+0

Bạn được chào đón. –

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