◆
JavaScript 继承详解:原型链继承等实现方式
原型链继承
构造函数、原型和实例之间的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个原型对象的指针。
继承的本质就是复制,即重写原型对象,代之以一个新类型的实例。
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function () {
return this.property;
};
function SubType() {
this.subproperty = false;
}
// 这里是关键,创建SuperType的实例,并将该实例赋值给SubType.prototype
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function () {
return this.subproperty;
};
var instance = new SubType();
console.log(instance.getSuperValue()); // true
存在的缺点:多个实例对引用类型的操作会被篡改。
function SuperType() {
this.colors = ['red', 'blue', 'green'];
}
function SubType() {}
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push('black');
console.log(instance1.colors); // ['red', 'blue', 'green', 'black']
var instance2 = new SubType();
instance1.colors.shift();
console.log(instance2.colors); // ['blue', 'green', 'black']
构造函数的继承
使用父类的构造函数来增强子类实例,等同于复制父类的实例给子类(不使用原型)
function SuperType() {
this.colors = ['red', 'green', 'blue'];
}
function SubType() {
// 继承自SuperType
SuperType.call(this);
}
var instance1 = new SubType();
instance1.colors.push('black');
console.log('instance1.colors:', instance1.colors); // ['red', 'green', 'blue', 'black']
var instance2 = new SubType();
console.log('instance2.colors:', instance2.colors); // ['red', 'green', 'blue']
instance1.colors.shift();
console.log('instance1.colors:', instance1.colors); // ['green', 'blue', 'black']
console.log('instance2.colors:', instance2.colors); // ['red', 'green', 'blue']
核心代码是 SuperType.call(this),创建子类实例时调用 SuperType 构造函数,于是 SubType 的每个实例都会将 SuperType 中的属性复制一份。 缺点:
- 只能继承父类的实例属性和方法,不能继承原型属性/方法
- 无法实现复用,每个子类都有父类实例函数的副本,影响性能
组合继承
组合上述两种方法就是组合继承。用原型链实现对原型属性和方法的继承,用借用构造函数技术来实现实例属性的继承。
function SuperType(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function () {
alert(this.name);
};
function SubType(name, age) {
// 继承属性
// 第二次调用SuperType()
SuperType.call(this, name);
this.age = age;
}
// 继承方法
// 构建原型链
// 第一次调用SuperType()
SubType.prototype = new SuperType();
// 重写SubType.prototype的constructor属性,指向自己的构造函数SubType
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function () {
alert(this.age);
};
var instance1 = new SubType('Nicholas', 29);
instance1.colors.push('black');
alert(instance1.colors); //"red,blue,green,black"
instance1.sayName(); //"Nicholas";
instance1.sayAge(); //29
var instance2 = new SubType('Greg', 27);
alert(instance2.colors); //"red,blue,green"
instance2.sayName(); //"Greg";
instance2.sayAge(); //27

还没有留言,来发表第一条吧~