1肋联、原型鏈
如何實現(xiàn)
function SuperType() {
this.color = 'green';
}
SuperType.prototype.getSuperColor = function () {
return this.color;
}
function SubType() {
this.SubColor = 'red'
}
SubType.prototype = new SuperType();
SubType.prototype.getSubColor = function () {
return this.SubColor;
}
var instance = new SubType();
alert(instance.getSuperColor()); // 'green'
存在的問題
最主要的問題就是包含引用類型值的原型谬擦。
function Super() {
this.colors = ['red', 'green'];
}
function Sub() {
}
Sub.prototype = new Super();
var instance1 = new Sub();
var instance2 = new Sub();
instance1.colors.push('blue');
console.log(instance1.colors); // ["red", "green", "blue"]
console.log(instance2.colors); // ["red", "green", "blue"]
總結(jié)
很少單獨使用原型鏈來實現(xiàn)繼承颗品。
2、借用構(gòu)造函數(shù)(偽造對象侧巨、經(jīng)典繼承)
如何實現(xiàn)
# 基本實現(xiàn)繼承
function Super() {
this.colors = ['red', 'green'];
}
function Sub() {
Super.call(this);
}
var instance1 = new Sub();
var instance2 = new Sub();
instance1.colors.push('blue');
console.log(instance1.colors); // ["red", "green", "blue"]
console.log(instance2.colors); // ["red", "green"]
# 子類型構(gòu)造函數(shù)中向超類型構(gòu)造函數(shù)中傳遞參數(shù)
function Super(name) {
this.name = name;
}
function Sub() {
Super.call(this, 'tom');
this.age = 24;
}
var instance = new Sub();
console.log(instance.name); // tom
console.log(instance.age); // 24
存在的問題
方法也必須在超類型構(gòu)造函數(shù)中定義,在超類型的原型上定義的方法不能成功繼承給子類型的實例鞭达。
function Super() {
this.fruit = 'orange';
}
Super.prototype.getSuperFruit = function () {
return this.fruit;
}
function Sub() {
Super.call(this);
}
var instance = new Sub();
alert(instance.getSuperFruit()); // instance.getSuperFruit is not a function
總結(jié)
很少單獨使用借用構(gòu)造函數(shù)實現(xiàn)繼承司忱。
3、組合繼承 (偽經(jīng)典繼承)
如何實現(xiàn)
function Super(name) {
this.name = name;
this.colors = ['red', 'green'];
}
Super.prototype.getSuperName = function () {
return this.name;
}
function Sub(name) {
Super.call(this, name);
this.age = 24;
}
Sub.prototype = new Super();
Sub.prototype.constructor = Sub;
var instance = new Sub('tom');
console.log(instance.name); // tom
console.log(instance.getSuperName()); // tom
存在的問題
最大的問題就是無論在什么樣的情況下畴蹭,都會調(diào)用倆次超類型構(gòu)造函數(shù):一次是在創(chuàng)建子類型原型的時候坦仍,另一次是在子類型構(gòu)造函數(shù)的內(nèi)部。雖然子類型最終會包含超類型對象的全部實例屬性叨襟,但我們不得不在調(diào)用子類型構(gòu)造函數(shù)時重寫這些屬性繁扎。
總結(jié)
組合繼承是javascript
中最常用的繼承模式。
4 、原型式繼承梳玫。
如何實現(xiàn)
# 基本的實現(xiàn)方式
function object(o) {
function F() {
}
F.prototype = o;
return new F();
}
var person = {
name: 'tom',
fruit: ['orange', 'banana']
};
var anotherPerson = object(person);
anotherPerson.name = 'jack';
anotherPerson.fruit.push('apple');
var yetAnotherPerson = object(person);
yetAnotherPerson.name = 'alice';
yetAnotherPerson.fruit.push('grape');
console.log(yetAnotherPerson.fruit); // ["orange", "banana", "apple", "grape"]
# ECMAScript 5 封裝的 Object.create()方法
var person = {
name: 'tom',
fruit: ['orange', 'banana']
};
var anotherPerson = Object.create(person);
anotherPerson.name = 'jack';
anotherPerson.fruit.push('apple');
var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = 'alice';
yetAnotherPerson.fruit.push('grape');
console.log(yetAnotherPerson.fruit); // ["orange", "banana", "apple", "grape"]
存在的問題
包含引用類型值得屬性始終都會共享相應(yīng)的值爹梁。
總結(jié)
在沒有必要興師動眾地創(chuàng)建構(gòu)造函數(shù),而只想讓一個對象與另一個對象保持類似的情況下提澎,原型式繼承是完全可以勝任的姚垃。
5、寄生式繼承
如何實現(xiàn)
function object(o){
function F() {
}
F.prototype = o;
return new F();
}
function createAnother(o) {
var clone = object(o);
clone.sayHi = function () {
alert('hi~');
}
return clone;
}
var person = {
name: 'tom',
colors: ['red', 'green', 'blue']
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi(); // 'hi~'
總結(jié)
在主要考慮對象而不是自定義類型和構(gòu)造函數(shù)的情況下盼忌,寄生式繼承也是一種有用的模式积糯。
6、寄生組合式繼承
如何實現(xiàn)
function SuperType(name) {
this.name = name;
this.colors = ['red', 'green', 'blue'];
}
SuperType.prototype.sayHi = function () {
alert('hi~' + this.name);
};
function SubType(name, age) {
SuperType.call(this, name);
this.age = age;
}
function inheritPrototype(subType, superType) {
var prototype = Object.create(superType.prototype);
prototype.constructor = subType;
subType.prototype = prototype;
}
inheritPrototype(SubType, SuperType);
var another = new SubType('jack', 24);
another.sayHi(); // 'hi jack'
console.log(another);
總結(jié)
寄生組合式繼承是引用類型最理想的繼承范式谦纱。