首先给出如下两个构造函数
function Animal(){ this.species = "动物"; } function Cat( name, color){ this.name = name; this.color = color; }
一、构造函数的绑定
使用apply 将父对象的构造函数绑定在子对象上
在子对象上加apply那一行就可以了
function Cat( name, color){ Animal.apply(this, arguments); this.name = name; this.color = color; } var cat11 = new Cat("11", "绿色"); console.log(cat11.species);
二、prototype 模式
Cat的prototype 对象指向一个Animal的实例,所有猫的实例都能继承Animal
// 如果替换prototype对象,下一步需要将这个新的prototype对象加上constructor属性,并指向原来的构造函数 Cat.prototype = new Animal(); Cat.prototype.constructor = Cat;
var cat13 = new Cat("大毛", "黄色"); console.log(cat13.species);
三、直接继承prototype
需要将Animal 改写
function Animal(){ } Animal.prototype.species = "动物";
Cat.prototype = Animal.prototype; Cat.prototype.constructor = Cat; var cat14 = new Cat("14", "黄色");
这样做有点是效率高,缺点是Cat.prototype 和 Animal.prototype 指向同一个对象,任何对Cat.prototype 的修改 都会直接影响 Animal.prototype 的修改
四、利用空对象作为中介
var p = function() {}; p.prototype = Animal.prototype;
// Cat的prototype指向p的实例,Cat的实例可以继承p
// 相当于删除了原先的值,然后赋予了一个新值
Cat.prototype = new p();
// Cat.prototype.constructor指向p 所以要加下面一行 Cat.prototype.constructor = Cat;
封装成函数
function extend(Child, Parent) { var p = function() {}; p.prototype = Parent.prototype; Child.prototype = new p(); Child.prototype.constructor = Child; //备用方法 Cat.uber = Parent.prototype; } extend(Cat, Animal); var cat = new Cat("小猫", "米色");
五、拷贝
function extend(Child, Parent) { var c = Child.prototype;
var p = Parent.prototype;
for ( var i in p) { c[i] = p[i]; }
c.uber = p;
}
extend( Cat, Animal);
注:参考阮一峰