标签:es5 name Parent 继承 如何 Child 父类 构造函数
ES5如何实现继承
一.原型链继承
原型链继承的原理很简单,直接让子类的原型对象指向父类实例,当子类实例找不到对应的属性和方法时,就会往它的原型对象,也就是父类实例上找,从而实现对父类的属性和方法的继承
function Prant() { this.name = 'hello' } Prant.prototype.getName = function() { return this.name; } function child() {} // 子类 //让子类的原型对象指向父类实例, 这样一来在Child实例中找不到的属性和方法就会到原型对象(父类实例)上寻找 child.prototype = new Prant(); // 根据原型链的规则,顺便绑定一下constructor, 这一步不影响继承, 只是在用到constructor时会需要 child.prototype.constructor = child; const alias = new child(); alias.name //hello alias.getName(); //hello
缺点:
- 由于所有Child实例原型都指向同一个Parent实例, 因此对某个Child实例的父类引用类型变量修改会影响所有的Child实例
- 在创建子类实例时无法向父类构造传参, 即没有实现
super()
的功能
二.构造函数继承
构造函数继承,即在子类的构造函数中执行父类的构造函数,并为其绑定子类的this
,让父类的构造函数把成员属性和方法都挂到子类的this
上去,这样既能避免实例之间共享一个原型实例,又能向父类构造方法传参
function Parent(name) { this.name = [name] } Parent.prototype.getName = function() { return this.name } function Child() { // 子类 Parent.call(this, 'hello') } const child1 = new Child(); const child2 = new Child(); child1.name[0] = '构造函数继承'; console.log(child1.name) // 构造函数继承 console.log(child2.name) //hello child2.getName(); // 找不到,报错
缺点:
- 继承不到父类原型上的属性和方法
三.组合式继承
将以上两者组合起来使用
function Parent(name) { this.name = [name] } Parent.prototype.getName = function() { return this.name } function Child() { // 构造函数继承 Parent.call(this, 'zhangsan') } //原型链继承 Child.prototype = new Parent() Child.prototype.constructor = Child //测试 const child1 = new Child() const child2 = new Child() child1.name[0] = 'hello' console.log(child1.name) // ['hello'] console.log(child2.name) // ['zhangsan'] child2.getName() // ['zhangsan']
缺点:
- 每次创建子类实例都执行了两次构造函数(
Parent.call()
和new Parent()
),虽然这并不影响对父类的继承,但子类创建实例时,原型中会存在两份相同的属性和方法,这并不优雅
四.寄生式组合继承
解决构造函数被执行两次的问题, 我们将指向父类实例
改为指向父类原型
, 减去一次构造函数的执行
function Parent(name) { this.name = [name] } Parent.prototype.getName = function() { return this.name } function Child() { // 构造函数继承 Parent.call(this, 'zhangsan') } //原型链继承 // Child.prototype = new Parent() Child.prototype = Object.create(Parent.prototype) //将`指向父类实例`改为`指向父类原型` Child.prototype.constructor = Child //测试 const child = new Child() const parent = new Parent() child.getName() // ['zhangsan'] parent.getName() // 报错, 找不到getName()
目前最成熟的继承方式,js高级体现。
回顾:
说到js继承,最开始想到的应该是是原型链继承
,通过把子类实例的原型指向父类实例来继承父类的属性和方法,但原型链继承的缺陷在于对子类实例继承的引用类型的修改会影响到所有的实例对象
以及无法向父类的构造方法传参
。构造函数继承
, 通过在子类构造函数中调用父类构造函数并传入子类this来获取父类的属性和方法,但构造函数继承也存在缺陷,构造函数继承不能继承到父类原型链上的属性和方法
。
后面有了组合式继承,但也有了新的问题,每次都会执行两次父类的构造方法,最终有了寄生式组合式继承。
标签:es5,name,Parent,继承,如何,Child,父类,构造函数 来源: https://www.cnblogs.com/huanxiongs02/p/14697932.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。