《JS高级程序设计》第6章的读书笔记
- 创建对象(一)工场模式和构造函数模式
- 创建对象(二)原型模式和组合模式
- 创建对象(三)再探原型
- 对象继承(一)原型链
- 对象继承 (二)借用构造函数和组合继承
- 对象继承(三)原型式继承和寄生式继承
- 对象继承(四)寄生组合式继承
1 借用构造函数
为了解决原型链继承引起的不同实例共享引用类型值
的问题,开发人员开始使用一种叫constructor stealing的技术,也叫做伪造对象或经典继承。
这种技术的思想是:在子类型构造函数的内部调用超类型构造函数。
看下面的代码:
function SuperType() {
this.colors = ['red', 'blue', 'green'];
}
function SubType() {
SuperType.call(this);
}
let instance1 = new SubType();
instance1.colors.push('black');
console.log(instance1.colors); //[ 'red', 'blue', 'green', 'black' ]
let instance2 = new SubType();
console.log(instance2.colors); // [ 'red', 'blue', 'green' ]
代码实现了:在子类型构造函数中,调用父类型构造函数,call()可以改变了父类型函数的作用域,所以父类型构造函数中的this是子类型实例。结果是:所有子类型实例都有了各自的colors实例。从而不用逐一覆盖这个引用类型的值。
传递参数
借用构造函数不仅解决了引用类型共享的问题,还解决了向超类型构造函数传递参数的问题。
show your my code
function SuperType(name) {
this.name = name;
}
function SubType() {
SuperType.call(this, 'achao');
this.age = 29;
}
let instance = new SubType();
console.log(instance.name); //achao
console.log(instance.age); // 29
name
属性是属于子类型实例,不会被实例共享。
借用构造函数的问题
仅仅是借用构造函数,那么无法共享方法,也就是无法函数复用。
2 组合继承
原型链模式存在共享引用类型的问题,借用构造函数存在无法共享方法的问题。那么,一种结合了原型链模式和借用构造函数的新继承模式,就出现了。这种新模式取两者之长,被称为组成继承(combination inheritance),也就伪经典继承,成为JS中最常用的继承模式。
还是看代码
function SuperType(name) {
this.name = name;
this.colors = ['red', 'blue', 'green'];
}
SuperType.prototype.sayName = function() {
console.log(this.name);
}
function SubType(name, age) {
SuperType.call(this, name);
this.age = age;
}
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
//因为要用到constructor SubType上的属性,所以要重写子类型原型对象的constructor属性
SubType.prototype.sayAge = function() {
console.log(this.age);
}
let instance1 = new SubType('Nicholas', 29);
instance1.colors.push('black');
console.log(instance1.colors); //[ 'red', 'blue', 'green', 'black' ]
instance1.sayName(); //Nicholas
instance1.sayAge(); //29
let instance2 = new SubType('Greg', 27);
console.log(instance2.colors); //[ 'red', 'blue', 'green' ]
instance2.sayName(); //Greg
instance2.sayAge(); //27
结果是方法共享(得益于原型链),实例有各自的引用类型(而且可以向超类型构造函数传递参数,这得益于借用构造函数),避免了原型链和构造函数各自的缺点。正如上文所说,这是最常见的继承模式。
3 小结
本文讲了借用构造函数和组合继承这两种继承方式。后续还有3种继承方式需要讨论。