JavaScript构造函数继承的几个方法
js构造函数中的五种继承方法
两个对象的构造函数,动物类
function Animal(){
this.species = "动物";
}
function Cat(name,color){
this.name = name;
this.color = color;
}
怎么让猫继承动物类呢?有五种方法供我们使用
一、构造函数方法
用call或者apply方法将父对象的构造函数绑定在子函数身上
function Cat(name,color){
// 将animal实例构造函数绑定到子函数上
Animal.apply(this,arguments);
this.name=name;
this.color=color;
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物
}
二、prototyp模式
function Animal(){
this.species = "动物";
}
function Cat(name,color){
this.name = name;
this.color = color;
}
// console.log(Cat.prototype);出现的是一个object对象,其构造函数指向Cat
//console.log(Cat.constructor);出现的是一个空的函数定义,因为Cat类似于一个实例对象,而cat.prototype才指向原型对象
//console.log(Cat.prototype.constructor);出现的是cat原型的函数定义
Cat.prototype=new Animal();//相当于是将animal设置成了cat原型的原型
//console.log(Cat.prototype);出现的是一个anima对象,构造函数是animal()
//console.log(Cat.constructor);任然是一个空的函数定义,因为第一句相当于删除了prototype属性
//console.log(Cat.prototype.constructor);出现的是function animal,因为将Cat.prototype指向了animal
Cat.prototype.constructor=Cat;
//原本Cat.prototype.constructor指向的是cat,而Cat.prototype=new Animal();将Cat的原型指向了animal,所以此时Cat.prototyp
//e.constructor将会等于animal,这样会导致继承连的紊乱,所以需要手动纠正
//console.log(Cat.prototype);出现animal对象,constructo指向cat,所以继承成功
//console.log(Cat.constructor);
//console.log(Cat.prototype.constructor);
// var cat1 = new Cat("大毛","黄色");
// alert(cat1.constructor == Animal);
这显然会导致继承链的紊乱(cat1明明是用构造函数Cat生成的),因此我们必须手动纠正,将Cat.prototype对象的constructor值改为Cat。这就是第二行的意思。
这是很重要的一点,编程时务必要遵守。下文都遵循这一点,即如果替换了prototype对象,
o.prototype = {};
那么,下一步必然是为新的prototype对象加上constructor属性,并将这个属性指回原来的构造函数。
o.prototype.constructor = o;
三,直接继承prototype
由于prototype属性可以直接保存不变的属性,所以我们只需要设置
function Animal(){ }
Animal.prototype.species = "动物";
Cat.prototype = Animal.prototype;
Cat.prototype.constructor = Cat;
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物
上述即可,但是这样做有一个缺点,因为cat和animal原型指向了一个对象即Cat.prototype = Animal.prototype;所以任何对cat.prototype的修改也会影响到Animal(类似指针)
四。YUI框架的写法(利用空对象进行拷贝)
var F = function(){};
F.prototype = Animal.prototype;
Cat.prototype = new F();
Cat.prototype.constructor = Cat;
利用中间变量F保存了Animal.prototype,然后将cat设置为F的实例,所以Cat.prototype的修改相当于是F实例的修改,然不会改变Animal.prototype的值,而且F为空,几乎不占内存,然后将上述封装成一个函数
function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
extend(Cat,Animal);
var cat1 = new Cat("大毛","黄色");
alert(cat1.species); // 动物
还有一种不常用,不做介绍了。
ps:不知道为什么copy过来的代码会出现格式紊乱

浙公网安备 33010602011771号