你应该要知道的JS继承
是什么?
- 继承是面向对象技术中的一个概念;
- 如果一个类继承了另一个类,那么该类就是子类,被继承的类就是父类(超类);
- 继承后的优点:
- 子类可以继承父类的所有属性和方法;
- 子类可以重写属性和方法;
怎么实现?
其实继承的含义非常简单,我们更应该怎么实现继承,继承的方式有那些? 说到继承,我们就会立马想到ES6里面的extends;如果不用extends语法糖,你又能想到哪几种方式呢?
- 原型链继承
- 涉及到构造函数,原型,实例之间的关系;
- 简单来说就是用父构造函数的实例重写子构造函数的原型,那么有原型链的存在,子构造函数的所有实例都能访问到父构造函数的属性和方法;但是原型里面的属性和方法是公共的,任何的修改都会对其他实例造成影响;
- 构造函数继承
- 利用call()方法改变this指向;
- 使用call()方法将父类里面的this指向子类,那么在new一个实例的时候,子类实例里面就有了父构造函数里面的属性和方法;
- 值得注意的是call()方法必须放在第一行;
- 使用call()方法,只能继承父构造函数本身的属性和方法,不能继承其原型对象里面定义的属性和方法;会报错;
- 组合式继承
- 组合式继承就是将上面两种方式结合起来;
- call()方法是为获取父类本身的属性和方法;同时这种方式获取属性和方法,子类实例之间的改变不会相互影响,因为实例本身有的话,就不会到原型对象上面去找;
- 用父构造函数重写子构造函数的原型,是为了获取父构造函数原型对象里面的属性和方法;
- 在Parent的原型对象上定义方法时,要注意不要用箭头函数,这时候的this是指向window;
- Parent()执行了两次,造成了性能的浪费;
- 原型式继承
- 使用Object.create(proto),主要是对普通对象的继承;
- 既然用到Object.create()这个方法,那么首先先来了解一下这个方法:
- Object.create(proto)用于创建一个新的对象,并将传入的对象作为新对象的原型;proto这个参数可以传null;
- Object.create()是浅拷贝,多个实例的引用数据类型指向相同的内存地址,会相互影响;
- 寄生式继承
- 在原型式继承的基础上对创建新的对象的过程进行封装,同时可以为新的对象添加新的属性和方法;
- 寄生式继承本质上还是多个实例共享同一个原型对象,所以改变属性还是会相互影响;
- 寄生组合式继承
- 这种方式算是对组合式继承的一直优化,利用Object.create()方法减少一次对Parent()的调用,优化性能;
- 总的来说,是最优的继承方案;
- 使用call()函数继承父类本身的属性和方法;
- 使用Object.create()方法将父类的原型对象赋值为新对象的原型,这样就能使用父类原型对象里面的属性和方法;同时减少一次Parent()的调用,优化性能;
介绍了这么多实现继承的方法,我相信大家对继承有进一步的认识了;大家肯定会说,这些实现的方式太过于麻烦,并且各有各的问题,无法在实际的开发环境中很好使用;基于这样的问题,ES6中extends语法糖就很好的解决了这个问题;让继承更加的简单,便捷;
- extends继承
- 在上面的几种方式中,可以看到都是由构造函数之间实现继承并生成实例,ES6中提供了更接近面向对象的写法,引入了类的概念,使用class定义;
- ES6的class可以看作是一个语法糖,它的绝大部分的功能,ES5里面的构造函数都可以做到,类只是让原型的写法更加清晰;
- constructor()构造函数用来定义属性,在类中定义的方法不需要加function,直接使用方法的简写方式;其实直接在类中定义的方法,相当于定义在构造函数的原型对象上;
这就是JS继承的几种方式,当然关于类还有很多的点可以去探讨;
如果各位小伙伴觉得文章还行,希望多多点赞;也可以在评论区列出自己熟悉的JS里面的知识点,互相学习!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站。本站所有源码与软件均为原作者提供,仅供学习和研究使用。如您对本站的相关版权有任何异议,或者认为侵犯了您的合法权益,请及时通知我们处理。