原型继承和原型污染
- 父类的内部属性在继承后在子类的原型对象上,父类本身不会被修改。同时子类继承父类的属性后,所有子类的实例共同指向一个原型,所以会发生污染。
- 父类与子类有相同命名的属性也不会冲突,子类优先使用自身定义的属性,如果没有找到就去找父类原型的属性
function father(name) {
this.name = name
this.colors = ["red", "blue", "green"];
}
// father.prototype.colors = ["red", "blue", "green"];
function son(name) {
this.name = name
}
son.prototype = new father('ppp');
var p1 = new father()
var son1 = new son('aaa');
var son2 = new son();
son1.colors.push("black");
console.log(p1.colors, son1.colors, son2.colors); // 原型继承导致子类实例修改了原型上的变量和属性
- 子类继承父类后,也会继承父类的原型,同样这个(爷爷辈)的原型也会被污染,从而影响到父类
function father(name) {
this.name = name
// this.colors = ["red", "blue", "green"];
}
father.prototype.colors = ["red", "blue", "green"];
function son(name) {
this.name = name
}
son.prototype = new father('ppp');
var p1 = new father()
var p2 = new father()
var son1 = new son('aaa');
var son2 = new son();
son1.colors.push("black");
// 所有father类的实例都被污染了
不污染父类的继承
- call 函数将父类的变量引用在子类中,不借助原型将属性一同交给子类本身,但不能继承父类原型上的方法
// function son() {
// father.call(this)
// }
- 浪费开销,每一个子类都用了父类
- 虽然子类使用了父类的属性,但二者没有原型的关联,所以要将子类的原型关联到父类上
son.prototype.constructor = new father()
当父类原型上发生变化后,子类也能在原型上找到父类的原型并使用它的属性和方法