继承,ECMAScript只支持实现继承,而且其实现继承主要是依靠原型链来实现的
构造函数、原型、和实例的关系:每个构造函数都有一个原型对象,每个原型对象都包含一个指向构造函数的指针,每个实例都包含一个指向原型对象的内部指针
如果我们让一个原型对象等于另一个类型的实例,会怎么样呢?这样的关系层层递进,就是继承
我们知道,所有的引用类型默认都继承了Object,这个继承也是通过原型链实现的,这也是所有自定义类型都会继承toString()、valueOf()等默认方法的根本原因
确定原型和实例的关系
1使用instanceof操作符,用来测试实例与原型链中 出现过的 构造函数,结果就会返回true
alert(str instanceof Object); //true
alert(str instanceof SubType); //true
2使用isPrototypeOf()方法,只要是在原型链中 出现过的 原型,都可以说是该原型链所派生的实例的原型,返回true
alert(Object.prototype.isPrototypeOf(str)); //true
原型链的问题是共享和不能传递参数
借用构造函数
借用构造函数,技术思想:在子类型构造函数内部调用超类型构造函数,函数只不过是在特定环境中执行代码的对象,因此可以通过使用apply()和call()方法在(将来)新创建的对象上执行构造函数
相对于原型链,借用构造函数有一个很大的优势,可以在子类型中向超类型构造函数传递参数
function SuperType(name){
this.name=name;
}
function SubType(){
SuperType.call(this,"Nicholas");
this.age=29;
}
var instance=new SubType();
alert(instance.name); //"Nicholas"
alert(instance.age); //29
单独使用借用构造函数也是有问题的,函数的复用无从谈起
组合继承
组合继承便是将原型链与借用构造函数的长处添加在一起
思路:使用原型链实现对原型属性和方法的继承,通过借用构造函数实现对实例属性的继承
ECMAScript 5新增Object.create()方法规范了原型式继承,这个方法接受2个参数,第一个参数用作新对象原型的对象,第二个参数(可选)为新对象定义额外属性的对象
var person={
name:"Nicholas",
friends:["Shelby","Court","Van"]
};
var anotherPerson=Object.create(person,{
name:{
value:"Greg"
}
});
alert(anotherPerson.name); //"Greg"