2015-07-03 22 views
5

Tôi nghĩ rằng tôi hiểu thừa kế nguyên mẫu trong JS nhưng tôi gặp khó khăn khi viết mã để chứng minh một ý tưởng cụ thể mà tôi có. Hãy xem xét kịch bản cực kỳ đơn giản này, nơi các đối tượng quản lý xuất phát từ đối tượng Employee:Thừa kế nguyên mẫu không có mẫu thử nghiệm?

function Employee() 
{ 
    this.name = "Axel"; 
    this.dept = "R&D"; 
} 

function Manager() 
{ 
    Employee.call(this); 
    this.reports = ["Report 1", "Report 2", "Report 3"]; 
} 

console.log(new Manager()); 

Đầu ra là:

Manager {name: "Axel", dept: "R&D", reports: Array[3]} 

Lạ lùng thay, có vẻ như với tôi rằng chúng tôi đã thành công trong việc chứng minh quyền thừa kế nguyên mẫu. Nhưng sự thật là chúng tôi đã không sử dụng prototype ở bất cứ nơi nào làm phiền tôi. Chắc chắn đoạn mã trên không phải là cách để làm điều đó?

Ai đó có thể cung cấp ví dụ cho thấy cách tiếp cận trên không thành công?

(Bằng cách này, ví dụ xuất phát từ các tài liệu chính thức của Mozilla, trừ các thiết lập của nguyên mẫu: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Details_of_the_Object_Model)

+0

Không có gì sai với cách tiếp cận trên. Trong trường hợp này, bạn chỉ sửa đổi một đối tượng * duy nhất *, trong khi với nguyên mẫu, bạn có thể sửa đổi * tất cả các đối tượng * với cùng một mẫu thử nghiệm. – meskobalazs

+0

@meskobalazs Tôi sợ tâm trí được đào tạo theo kiểu cổ điển của tôi không tuân theo. Nếu tôi viết một loạt các 'mới Manager() 'tôi sẽ không nhận được tất cả ba tài sản (tên, dept và báo cáo)? Như vậy, có vẻ như với tôi rằng __all objects__ xa hơn xuống đường được sửa đổi. – dotslash

+2

Bạn không sử dụng nguyên mẫu hoặc thừa kế nguyên mẫu ở đây. Thay vào đó, bạn đang thiết lập các thuộc tính trực tiếp trên từng đối tượng riêng lẻ. –

Trả lời

2

Chúng tôi đã thực hiện điều này xung quanh trong các nhận xét khác nhau, nhưng tôi muốn đưa ra một ví dụ có thể giúp làm rõ mọi thứ. Bắt đầu với mã ban đầu của bạn:

function Employee() 
{ 
    this.name = "Axel"; 
    this.dept = "R&D"; 
} 

function Manager() 
{ 
    Employee.call(this); 
    this.reports = ["Report 1", "Report 2", "Report 3"]; 
} 

console.log(new Manager()); 

Chúng tôi cũng có thể làm chính xác điều tương tự như vậy:

function setEmployee(emp) 
{ 
    emp.name = "Axel"; 
    emp.dept = "R&D"; 
} 

function Manager() 
{ 
    setEmployee(this); 
    this.reports = ["Report 1", "Report 2", "Report 3"]; 
} 

console.log(new Manager()); 

Bây giờ chúng tôi đã không được sử dụng .call() hoặc .apply() hoặc bất cứ điều gì để ưa thích. Hàm tạo Manager chỉ cần gọi hàm khác và chuyển trực tiếp giá trị this làm đối số. Mã thực hiện chính xác điều tương tự như trước đây.

Chúng ta có thể mang nó một bước xa hơn:

function setEmployee(emp) 
{ 
    emp.name = "Axel"; 
    emp.dept = "R&D"; 
} 

function createManager() 
{ 
    var emp = {}; 
    setEmployee(emp); 
    emp.reports = ["Report 1", "Report 2", "Report 3"]; 
    return emp; 
} 

console.log(createManager()); 

Bây giờ chúng ta không sử dụng nhà thầu, và thậm chí không sử dụng this - chúng tôi chỉ tạo ra một đối tượng một cách rõ ràng và đi qua nó xung quanh giữa các chức năng, và mã vẫn làm điều tương tự!

+0

Cảm ơn bạn đã nỗ lực. Có, nó làm cho mọi thứ rất rõ ràng. – dotslash

1
new Manager() instanceof Manager 
> true 
new Manager() instanceof Employee 
> false 
+0

Tuyệt vời! Ít nhất nó được xác nhận tôi đã làm vô nghĩa trong tên của thừa kế. : D – dotslash

2

Bạn không thực sự thừa hưởng bất cứ điều gì. Bạn chỉ cần "áp dụng" một chức năng trên một đối tượng nhất định. Tôi nghĩ nhiều ngôn ngữ chức năng có thể làm được điều này.

Thừa kế được sử dụng, tốt để kế thừa, không chỉ áp dụng các chức năng không liên quan trên một đối tượng nhất định.

Trong ví dụ của bạn, bạn không bao gồm cách kế thừa các phương thức chẳng hạn. Ngay cả khi bạn cố gắng triển khai kế thừa phương thức qua một số Proxy, ví dụ như điều này không có nghĩa là bạn đã kế thừa cha mẹ.

+0

Ah! Vì vậy, bạn có nghĩa là 'tên' và' dept' ở trên thuộc về 'Manager' và không phải' Employee'? Nếu vậy, làm thế nào tôi có thể xác nhận điều này? – dotslash

+1

Trong ví dụ của bạn, 'name' và' dept' không "thuộc về" 'Manager' hoặc' Employee'. Chúng là các thuộc tính mà bạn đang thiết lập trên từng đối tượng riêng lẻ và không có gì liên quan đến các nguyên mẫu của 'Manager' hoặc' Employee'. –

+0

Đặt một cách khác, khi tất cả được nói và thực hiện, bạn đã tạo một đối tượng với các thuộc tính riêng của nó mà bạn đã đặt rõ ràng trên đối tượng riêng lẻ. Nó không tạo ra sự khác biệt nào cho dù các thuộc tính đó được đặt trong hàm 'Manager' hay hàm' Employee' hoặc trong một số hàm ngẫu nhiên khác mà bạn gọi một cách rõ ràng. Trong mỗi trường hợp, chúng chỉ đơn giản là thuộc tính của đối tượng * riêng lẻ *. –

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