2015-05-16 139 views
1

我不敢問這個問題,因爲已經有很多關於同一主題。瞭解Javascript原型繼承

我想了解使用approach-1approach-2

簡單的繼承

function Person(name, age) { 
 
    this.name = name || "de-name"; 
 
    this.age = !!Number(age) ? Number(age) : 0; 
 
} 
 

 
Person.prototype.setName = function(name) { 
 
    this.name = name; 
 
    return this; 
 
} 
 

 
function Student(name) { 
 
    Person.call(this, name); // Copy instance properties of Person class 
 
    this.title = "Student"; 
 
} 
 

 
// Suggested way 
 
Student.prototype = Object.create(Person.prototype); 
 

 

 
// Possible approach-1 
 
// Student.prototype = Person.prototype; 
 

 
// Possible approach-2 
 
// Student.prototype = new Person();

回答

0

方法1和方法2的缺點/限制實際上是不一樣的,沒錯。在方法2中,您正在創建一個新實例Person,並將該新實例分配給Student的原型。

此外,你應該這樣來做:

var Student = Object.create(Person.prototype);

根據MDN

The Object.create() method creates a new object with the specified prototype object and properties.

所以,你不把它分配給學生的原型,您將其分配給學生本身,並且學生將人員作爲其原型。

1

在基於原型的語言中,通過克隆用作原型而不是類的現有對象來執行繼承。

因此,在每一種情況下,我們都應該考慮選擇用作原型的對象來確定行爲。

在方法1中,您將Student的原型設置爲與Person相同的原型對象。這意味着對Student.prototype所做的任何更改都將影響Person.prototype,反之亦然。

在方法2中,您將Student的原型設置爲一個新的Person對象,該對象將根據您的初始化代碼設置以下屬性{name: 'de-name', age: 0}。名稱屬性將被您在Student函數中對Person.call()的調用覆蓋。由於這是一個全新的對象,因此對Student.prototype的任何修改只會影響新的Student對象,並且此Person實例中用作原型的任何缺失屬性都將委派給Person.prototype

爲了詳細說明最後一點(遺漏的屬性通過原型鏈),下面是一個例子。假設我們添加一個新的方法greetPerson:(否則你得到一個沒有定義的錯誤)

Person.prototype.greet = function() { console.log("Hi! " + this.name;) } 

調用new Student().greet()將JavaScript的通過原型鏈檢查,直到達到相應的屬性

// Walking up the chain 
/* 1 */ new Student()  // doesn't have a greet property 
/* 2 */ Student.prototype // => Person {name: 'de-name', age: 0} 
// This person instance doesn't have a greet property either 
// because we instantiated it before adding the `greet` property 
/* 3 */ Person.prototype // Has a greet property which gets called 

Object.create的建議模式中,除了Object.create允許您執行differential inheritance之外,您的操作與Student.prototype = new Person()幾乎完全相同。您甚至可以添加其他屬性作爲其第二個參數:

Student.prototype = Object.create(Person.prototype, { 
    age: 16, 
    study: function() { console.log("But I'm sooo lazy!!!"); } 
}); 
0

方法-2意味着原型鏈中的一個附加對象。如果(new Student()).someAttr未在學生對象(new Student())中解析,則使用方法-2,將檢查人員對象(new Person())(因爲這就是Student.prototype中的內容),然後Person.prototype。通過方法1,沒有人物。