关系图:
基于上述关系图的理解,让原型对象等于另一个类型的实例,假如这个类型的原型又等于另一个类型的实例,这样层层递进,构成了实例和原型的链条。
关系图:
//组合构造函数模式和原型模式
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
};
function SubType() {
this.subproperty = false;
}
//继承了SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function() {
return this.subproperty;
};
var instance = new SubType();
console.log(instance.getSuperValue()); //true
console.log(instance.constructor === SuperType); //true
console.log(SubType.prototype.constructor === SuperType); //true
?
SubType继承了SuperType。继承是通过创建SuperType实例,然后赋值给SubType.prototype实现的。实现的本质是重写原型对象,代之以一个新类型的实例。
代码关系图:
关系结果:instance指向SubType的原型,Sub-Type的原型又指向SuperType的原型。
注意两点:
通过实现原型链,本质上扩展了原型搜索机制。调用instance.getSu-perValue()会经历三个搜索步骤:
所有函数的默认原型都是Object的实例,因此默认原型都会包含一个内部指针,指向Object.prototype。
继承关系图(完整版):
SubType继承了SuperType,而SuperType了继承Object。当调用instance.toString()时,实际上调用的是保存在Object.prototype中的那个方法。
instanceof操作符和isPrototypeOf()方法
//instanceof操作符
console.log(instance instanceof Object); //true
console.log(instance instanceof SuperType); //true
consolo.log(instance instanceof SubType); //true
//isPrototypeOf()方法
console.log(Object.prototype.isPrototypeOf(instance)); //true
console.log(SuperType.prototype.isPrototypeOf(instance)); //true
console.log(SubType.prototype.isPrototypeOf(instance)); //true
?
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
};
function SubType() {
this.subproperty = false;
}
//继承SuperType,这个在前
SubType.prototype = new SuperType();
//添加父类没有的方法,在后
SuperType.prototype.getSubValue = function() {
return this.subproperty;
};
//重写父类方法,在后
SubType.prototype.getSuperValue = function() {
return false;
};
var instance = new SubType();
console.log(instance.getSuperValue()); //false
var instanceSuper = new SuperType();
console.log(instanceSuper.getSuperValue()); //true
?
由上述结果可以看出:子类重写父类方法,只是屏蔽,原方法不变。
function SuperType() {
this.property = true;
}
SuperType.prototype.getSuperValue = function() {
return this.property;
};
function SubType() {
this.subproperty = false;
}
//继承
SubType.prototype = new SuperType();
//字面量定义方法会使上一句代码无效
SubType.prototype = {
getSubValue: function() {
return this.subproperty;
},
someOtherMethod: function() {
return false;
}
};
var instance = new SubType();
console.log(instance.getSuperValue()); //error
?
上述继承后字面量写原型对象的方法会导致下面的错误是因为:现在的原型包含的是一个Object的实例,而非SuperType的实例,因此我们设想中的原型链已经被切断,现在的SubType和SuperType没关系了。
//第一个问题
function SuperType() {
this.colors = ["blue", "red", "yellow"];
}
function SubType() {
}
//继承
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors); //"blue,red,yellow,black"
var instance2 = new SubType();
console.log(instance2.colors); //"blue,red,yellow,black"
?
instance2的colors输出和instance1的colors一样,是因为这属性不是他们自己的,是SuperType实例的,不是他们本身的。
原文:http://mirroravatar.iteye.com/blog/2190983