zl程序教程

您现在的位置是:首页 >  IT要闻

当前栏目

大厂面试必须掌握的六种继承方式,你会吗?

2023-02-26 10:19:00 时间

博主在阅读大量面经文章时发现无论是大厂面试还是小厂面试,无论是社招还是校招,只要考查JS基础,继承、原型、原型链都是绕不开的话题,所以本次希望和大家一起学习必须掌握的七种继承方式,博主将细致的分析每一种继承方式的原理、优缺点并给出在线的实现方式,这不仅仅对面试有帮助,还对我们理解JS的运行机制有帮助,让我们一起加油吧~顺便给个赞哦!

1:原型链继承

原理

原型链继承的原理是利用原型对象和实例之间的关系实现继承,实现这种继承的关键在于让子类的原型对象指向新创建的父类实例。

实现代码

// 1:原型链继承 function Father() {     this.name = 'justin'; } Father.prototype.getName = function () {     return this.name }  function Child() { } Child.prototype = new Father(); const child = new Child(); console.log(child.getName());

优缺点

  • 优点:实例可以继承的属性包括:实例的构造函数的属性,父类构造函数的属性,父类原型对象上的属性。
  • 缺点:一个实例修改了原型对象上的属性,另一个实例的原型属性也会被修改。新实例无法向父类构造函数传参。

下面这个例子展示了,原型链继承的缺点
大厂面试必须掌握的六种继承方式,你会吗?

在线实现

codeSandBox

2. 构造函数继承

原理

构造函数继承的核心在于:在子类构造函数中通过父类构造函数.call(this)来实现继承。

实现代码

// 2:构造函数继承 function Father() {     this.name = 'justin';     this.say = {haha: 111} }  function Child(age) {     Father.call(this);     this.age = age; }  const child1 = new Child(10); const child2 = new Child(20);  child1.say.haha = 222;  console.log(child1); console.log(child2);

优缺点

  • 优点
  1. 可以继承多个构造函数属性(通过多次call的调用)
  2. 解决了原型链继承中实例共享引用类型的问题
  3. 在子实例中可以向父实例中传参
  • 缺点
  1. 只继承了父类构造函数的属性,没有继承父类原型对象上的属性。
  2. 无法实现父类构造函数的复用,每次都要重新调用

在线实现

codeSandBox

(福利推荐:阿里云、腾讯云、华为云服务器最新限时优惠活动,云服务器1核2G仅88元/年、2核4G仅698元/3年,点击这里立即抢购>>>

3. 组合继承(组合指的是组合了原型链和构造函数的继承方式)

原理

结合了原型链和构造函数的继承方式,一是通过在子类构造函数中让父类构造函数调用call修改this指向,二是让子类构造函数的原型对象指向父类构造函数的实例。

实现代码

// 3:组合继承(组合指的是组合了原型链继承和构造函数继承) function Father(age) {     this.colors = ['red','pink'];     this.age = age; } Father.prototype.say = () => '你好'; function Child(name,age) {     // 构造函数的方式     Father.call(this,age);     this.name = name; }  // 原型链 Child.prototype = new Father(); Child.prototype.constructor = Child;  const child1 = new Child('张三',20); const child2 = new Child('李四',25); Child.prototype child1 child1.colors.push('black'); console.log(child1.colors); console.log(child2.colors); console.log(child1.say());

优缺点

  • 优点
  1. 可以继承父类构造函数上的属性和原型对象上的属性。
  2. 可以传参。
  3. 每个新实例引入的构造函数属性是私有的。
  • 缺点
  1. 调用了两次父类构造函数。
  2. 子类实例上的属性,同时存在于原型链上和子例身上,造成原型链污染。

在线实现

codeSandBox

4: 原型式继承

原理

利用一个空函数作为中介,让这个中介的原型对象指向需要继承的父类对象,然后返回这个函数的实例,即可完成原型式继承。

实现代码

// 4:原型式继承 function createObj(o) {     function F() { };     F.prototype = o;     return new F(); }  const obj = {     name: 'justin',     friends: [1, 2, 3, 4] } // 方式1 const m1 = createObj(obj); const m2 = createObj(obj); // 方式2 const m3 = Object.create(obj);  console.log(m1.name);  //justin console.log(m2.name);  //justin m1.friends.push(666);  console.log(m1.friends);  // [1,2,3,4,666] console.log(m2.friends);  // [1,2,3,4,666]

优缺点

  • 优点
  1. 类似于复制一个对象,用函数来包装。
  • 缺点
  1. 无法向父类传参。
  2. 父类的引用类型被子类共享。

在线实现

codeSandBox在线实现

5:寄生式继承

原理

寄生式继承是在原型式继承的基础上进行了一次增强,也就是通过增加一个函数,然后添加属性实现继承。

实现代码

// 5:寄生式继承 function objCopy(o) {     function F() {};     F.prototype = o;     return new F(); }  function enhanceObj(o) {     const clone = objCopy(o);     clone.say = function() {         return 'hi';     }     return clone; }  const obj = {     name: 'justin',     colors: [1,2,3] }  const m1 = enhanceObj(obj); const m2 = enhanceObj(obj);  console.log(m1.name);  //justin console.log(m1.colors); //[1,2,3] console.log(m1.say());  //hi  m1.colors.push(777) console.log(m2.colors); // [1,2,3,777]

优缺点

  • 优点
  1. 增强了原型式继承的能力。
  • 缺点
  1. 无法向父类传参。
  2. 父类构造函数的引用类型对象被子类实例共享。

在线实现

codeSandBox在线实现

6:寄生组合式继承

原理

寄生组合式继承结合了构造函数继承、寄生式继承,让子类的构造函数的原型对象指向原型式继承传过来的实例,同时这个实例的构造函数也指向子类构造函数,别忘了子类构造函数中还需要父类构造函数通过call改变this指向。

实现代码

// 6:寄生组合式继承 function Father(name) {     this.name = name;     this.colors = [1,2,3]; } Father.prototype.say = function() {     return 'hi'; }  function Child(name,age) {     Father.call(this,name);     this.age = age; } function createObj(o) {     function F() {}     F.prototype = o;     return new F(); }  function inheritPrototype(Child,Father) {     // 先构造一个指向父类构造函数原型对象的对象     const prototype = createObj(Father.prototype);     // 让这个对象的构造函数指向Child     prototype.constructor = Child;     Child.prototype = prototype; } inheritPrototype(Child,Father); const child1 = new Child('justin',666); const child2 = new Child('心飞扬',777); console.log(child1.colors); //[1,2,3] console.log(child2.colors); //[1,2,3] child1.colors.push(666);  console.log(child1.colors);  // [1,2,3,666] console.log(child2.colors);  // [1,2,3]

优缺点

  • 优点:这是目前最优的一种继承方式。
  1. 子类构造函数可以向父类传参。
  2. 只调用一次父类构造函数。
  3. 父类的引用类型属性不会被子类共享。

在线实现

codeSandBox在线实现

参考链接

  • JS继承 原型链继承、构造函数继承、组合继承、原型继承、寄生式继承、寄生组合继承
  • JavaScript常用八种继承方案
  • 盘点那些高频前端面试题:JS继承的六种方式

大厂面试必须掌握的六种继承方式,你会吗?


本站部分内容转载自网络,版权属于原作者所有,如有异议请联系QQ153890879修改或删除,谢谢!
转载请注明原文链接:大厂面试必须掌握的六种继承方式,你会吗?

你还在原价购买阿里云、腾讯云、华为云、天翼云产品?那就亏大啦!现在申请成为四大品牌云厂商VIP用户,可以3折优惠价购买云服务器等云产品,并且可享四大云服务商产品终身VIP优惠价,还等什么?赶紧点击下面对应链接免费申请VIP客户吧:

1、点击这里立即申请成为腾讯云VIP客户

2、点击这里立即注册成为天翼云VIP客户

3、点击这里立即申请成为华为云VIP客户

4、点击这里立享阿里云产品终身VIP优惠价

喜欢 (0)
[[email protected]]
分享 (0)