原型链
构造函数、原型、实例的关系:
- 每个构造函数都有一个原型对象
- 原型对象都包含一个指向构造函数的指针
- 实例都包含一个指向原型对象的内部指针
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()
alert(instance.getSuperValue()) // true
SubType继承了SuperType,SuperType继承了Object(函数的默认原型是Object的实例)
instance指向 SubType 的原型,SubType 的原型指向 SuperType
调用 instance.getSuperValue()
搜索路径:
instanceof:检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上
alert(instance instanceof Object)
alert(instance instanceof SuperType)
alert(instance instanceof SubType)
isPrototypeOf:检查一个对象是否存在于另一个对象的原型链上
alert(Object.prototype.isPrototypeOf(instance))
alert(SuperType.prototype.isPrototypeOf(instance))
alert(SubType.prototype.isPrototypeOf(instance))
原型链的问题
引用类型值的原型属性会被所有实例共享
function SuperType(){
this.colors = ["red","blue","green"]; // 数组(引用类型值)
}
function SubType(){}
SubType.prototype = new SuperType(); // 继承 SuperType
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); // "red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); // "red,blue,green,black"
构造函数
使用 apply()
和 call()
方法在新创建的对象上执行构造函数
在子类型构造函数中向超类型构造函数传递参数
function SuperType(name){
this.colors = ["red","blue","green"];
this.name = name;
}
function SubType(){
SuperType.call(this,"fanison"); // 继承 SuperType,同时传递参数(为SubType实例设置name属性)
this.age = 18; // 实例属性
}
var instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors,instance1.name,instance1.age) // "red,blue,green,black" "fanison" 18
var instance2 = new SubType();
console.log(instance2.colors,instance2.name,instance2.age) // "red,blue,green,black" "fanison" 18
组合继承
使用原型链实现对原型属性和方法的继承,通过构造函数实现对实例属性的继承
function SuperType(name){
this.colors = ["red","blue","green"];
this.name = name;
}
SuperType.prototype.sayName = function(){
alert(this.name);
}
function SubType(name,age){
SuperType.call(this,name); // 继承属性
this.age = age;
}
// 继承方法
SubType.prototype = new SuperType();
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
};
var instance1 = new SubType("fanison",18);
instance1.colors.push("black");
console.log(instance1.colors); // "red,blue,green,black"
instance1.sayName(); // "fanison"
instance1.sayAge(); // 18
var instance2 = new SubType("yafanison",20);
console.log(instance2.colors); // "red,blue,green,black"
instance2.sayName(); // "yafanison"
instance2.sayAge(); // 20