继承的方式
一:原型链继承
核心: 将父类的实例作为子类的原型
function Animal(){ this.sex='man' }; Animal.prototype={ color:'black' }; function Dark(){ }; Dark.prototype=new Animal(); Dark.prototype.age=18; var jack=new Dark();
缺点:无法多继承
子实例共享父类的属性(父类的实例属性sex)
二:构造继承
核心:使用父类的构造函数来增强子类实例,等于是复制父类的实例属性给子类(没用到原型)
function Animal(){
this.sex='man'; //可以拥有属性 }; Animal.prototype={ color:'black'; //不能拥有属性 }; function Dark(){ Animal.call(this); }; var jack=new Dark();
缺点:只能继承父类的实例方法属性,不能得到父类的原型属性,因为本质上jack还是子类的实例,而不是父类的实例,只是使用了父类的构造函数。
三:实例继承
核心:为父类实例添加新特性,作为子类实例返回
function Animal(){ }; Animal.prototype={ color: 'black' }; function Dark(){ var animal=new Animal(); animal.age=18; return animal; }; var jack=new Dark();
缺点:不能多继承
实例是父类的实例,而不是子类的实例
四:拷贝继承
核心:将父类实例的所有属性方法拷贝到子类的原型上,可以实现多继承
function Animal(){ }; Animal.prototype={ sex:'man' }; function Dark(){ var animal=new Animal(); for(var i in animal){ Dark.prototype[i]=animal[i] } }; Dark.prototype.age=18; var jack=new Dark();
缺点:耗内存
五:组合继承
核心:原型链继承(子类实例共用父类属性)和构造继承(不能继承父类的构造属性)组合使用
function Animal(name){ this.name=name; }; Animal.prototype={ sex:'man' }; function Dark(name){ Animal.call(this, name) }; Dark.prototype=new Animal(); Dark.prototype.color='black'; var jack=new Dark('jack');
缺点:调用了两次父类的构造函数,子类的实例jack将会在自身和原型链上都有name属性(父类的实例属性)。
六:寄生式组合继承
核心:在组合继承的基础上稍作改造使用一个中间类将父类的实例属性去掉
function Animal(name){ this.name=name; }; Animal.prototype={ sex:'man' }; function Dark(name){ Animal.call(this, name); }; (function(){ function Temp(){}; Temp.prototype=Animal.prototype; Dark.prototype=new Temp(); })(); var jack=new Dark();