什么是继承? 继承建立在面向对象基础上的一种代码复用方式,子类通过继承来复用父类的代码
1.原型链继承
过程:访问对象时,如果对象私有属性中没有该属性,会去对象的构造函数的prototype中查找。
构造函数拥有原型,实例对象通过prototype关键字可以访问原型
如果构造函数定义了与原型属性同名的本地属性,则本地属性会覆盖原型属性值。
本地属性可以在实例对象中被修改,但是不同实例对象之间不会相互打扰。
原型属性会影响所有实例对象,修改任何原型属性值,则该构造函数所有实例都会变化。
function SuperType(){ this.property = true; } SuperType.prototype.getSuperValue = functioin(){ return this.property; } //继承SuperType function SubType(){ this.subProperty = false; } SubType.prototype = new SuperType(); SubType.prototype.getSubValue = funtion(){ return this.subProperty; } 原型继承的实现:子类的prototype指向父类的实例 原型继承的特点:可以继承父类的原型属性 原型的缺点:1.无法向父类构造函数传参 2.所有子类实例原型都指向同一个父类实例,因此某个子类实例修改父类的引用类型会影响所有子类的实例 3.每个类型只有一个原型,不直接支持多继承
在JavaScript中,一切都是对象,函数是第一型。Function和Object都是函数的实例。
2.构造函数继承
为了解决原型继承不能传参和不能继承私有属性的缺点,使用构造函数继承。
function SuperType(property) { this.property = property; } function SubType(property) { SuperType.call(this, property); //子类给父类传参 } var instance1 = new SubType(false); console.log(instance1.property); // false var instance2 = new SubType(true); console.log(instance2.property); // true
构造函数继承的实现:在子类构造函数中使用call/apply调用父类构造函数,将父类构造函数指向子类实例
构造函数继承的特点:1.子类中可以给父类传参 2.可以继承父类的私有属性
构造函数的缺点:只能继承父类的私有属性,不能继承父类的原型属性
3.寄生组合式继承
组合继承实现了子类继承父类的私有属性和原型属性,但是有冗余问题?
解决:使用构造函数继承之后,不用原型继承,而用其他方法让子类继承父类的原型属性不继承父类的私有属性。
不给子类构造函数的prototype赋值为父类实例,赋值为一个只有父类的原型属性没有私有属性的对象,子类就不会继承父类私有属性了
// 根据传入的父类生成只继承父类原型的对象 function geSubtPrototype(SuperType) { function Func() {} //创建以一个构造函数 Func.prototype = SuperType.prototype; //构造函数的原型指向父类的原型 return new Func(); //返回父类的原型 }
function SuperType(property) { this.property = property; } SuperType.prototype.getSuperValue = function () { return this.property; } function SubType(property, subProperty) { SuperType.call(this, property); this.subProperty = subProperty; } SubType.prototype = geSubtPrototype(SuperType); SubType.prototype.getSubValue = function () { return this.subProperty; }
特点:1.子类继承父类的私有属性和原型属性 2.子类向父类传递参数。3.继承后没有冗余属性。
标签:属性,继承,子类,js,原型,父类,构造函数 From: https://www.cnblogs.com/baller-coder/p/17142881.html