我在前面介绍了,javascript的继承机制,还有如何“封装”数据和方法,今天再来说一说,如何来实现对象之间的“继承”。
先创建一个“动物”对象的构造函数。
function Animal(){
this.species = "动物";
}
再来创建一个“猫”对象的构造函数。
function Cat(name,color){
this.name = name;
this.color = color;
}
看我是如何是实现对象之间的继承,让Cat继承Animal的。
1.通过函数绑定
这种方法是比较简单的方法,使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行:
functionCat(name,color){
Animal.apply(this,arguments);
this.name= name;
this.color= color;
}
varcat1 = new Cat("大毛","黄色");
alert(cat1.species);// 动物
2.利用 prototype 模式
这种方法是比较常见的方法,主要利用了对象的prototype属性。
如果“Cat”的prototype对象,指向一个|Animal的实例,那么所有“猫”的实例,就能继承Animal了。
Cat.prototype= new Animal();
Cat.prototype.constructor= Cat;
varcat1 = new Cat("大毛","黄色");
alert(cat1.species);// 动物
ps:
第一行代码:我们将Cat的prototype对象指向了一个Animal的实例。它相当于完全删除了prototype对象原先的值,然后赋了新值。
第二行代码:因为每个对象的prototype对象都有一个constructor属性,指向自己的构造函数,执行完第一行代码后,该属性指向的是Animal。执行该代码后,可使得该属性重新指向Cat的构造函数,保证Cat构造函数的完整性。
接下来的代码就很容易理解了,就不再做详细解释了。
3.直接继承prototype
这种方式是第二种方式的改进。针对这样的情景
functionAnimal(){ }
Animal.prototype.species= "动物";
然后,将Cat的prototype对象,指向Animal的prototype对象,这样就完美的继承了。
Cat.prototype= Animal.prototype;
Cat.prototype.constructor= Cat;
varcat1 = new Cat("大毛","黄色");
alert(cat1.species);// 动物
Ps
该方法的优缺点也是比较明显的:
优点:
这样做的优点是效率比较高(不用执行和建立Animal的实例了),比较省内存
缺点:
缺点是Cat.prototype和Animal.prototype现在指向了同一个对象,那么任何对Cat.prototype的修改,都会反映到Animal.prototype。
上面第二行代码,虽然保证了Cat的prototype的constructor指向了Cat,但是此时Animal的prototype的constructor也指向了Animal。破坏了Animal的对象的完整性。
总结:通过这三种方式,完全可以满足我们“继承”的需要了,这里主要依靠于prototype的功劳,要想熟悉这几种方式,还是要下功夫了解一下prototype对象了。