这样回答继承可能面试官更满意

 更新时间:2019年12月10日 16:04:14   作者:蜗牛的北极星之旅lv-3  
这篇文章主要介绍了这样回答继承可能面试官更满意,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

9021年底了,突然想在这个最后一个月准备一下,试试机会,能否更进一步。所以开始准备一些基础知识,也随带总结出来给各位想换工作的同学。希望大家能找到自己想要的工作。祝大家好运!

一、何为继承

一个类获取另一个或者多个类的属性或者方法。继承可以使得子类具有父类的各种方法和属性。以免重复输出很多代码。

二、继承的原理

复制父类的方法和属性来重写子类的原型对象。

三、原型链继承

3.1 实现

function Father() {
  this.text = '1';
}
Father.prototype.someFn = function() {
  console.log(1);
}
Father.prototype.someValue = '2';

function Son(){
  this.text1 = 'text1';
}
// 函数原型指向构造函数的实例
Son.prototype = new Father();

3.2 优点

1、简单易操作。

3.3 缺点

1、父类使用this声明的属性被所有实例共享。原因是实例化是父类一次性赋值到子类实例的原型上,它会将父类通过this声明的属性也赋值到子类原型上。例如在父类中一个数组值,在子类的多个实例中,无论哪一个实例去修改这个数组的值,都会影响到其他子类实例。

2、创建子类实例时,无法向父类构造函数传参,不够灵活。

四、借用构造函数(call)

4.1 实现

function Father(...arr) {
  this.some = '父类属性';
  this.params = arr;
}
Father.prototype.someFn = function() {
  console.log(1);
}
Father.prototype.someValue = '2';
function Son(fatherParams, ...sonParams) {
  // Father的this指向Son的this
  // 使用call调用父类,Father将会立即被执行,并且将父类的Father的this执行Son
  // 的this。实例化子类,this将指向new期间创建的新对象,返回该新对象。
  Father.call(this, ...fatherParams);
  this.text = '子类属性';
  this.sonParams = sonParams;
}
var fatherParams = [];
var sonParams = [];
var sonInstance = new Son(fatherParams, ...sonParams);

4.2 优点

1、可以向父类传递参数。

2、解决父类this声明的属性会被实例共享的问题。

4.3 缺点

1、只能继承父类通过this声明的属性/方法。不能继承父类prototype上的属性/方法。

2、父类方法无法复用。每次实例化子类,都要执行父类函数。重新声明父类所定义的方法,无法复用。

五、组合继承(call+new)

原理:通过原型链继承来将this、prototype上的属性和方法继承制子类的原型对象上。使用借用构造函数来继承父类通过this声明的属性和方法在之子类的实例属性上。

5.1 实现

function Father(...arr) {
  this.some = '父类属性';
  this.params = arr;
}
Father.prototype.someFn = function() {
  console.log(1);
}
Father.prototype.someValue = '2';
function Son(fatherParams, ...sonParams) {
  // 借用构造函数继承父类this什么的属性和方法到子类实例属性上
  Father.call(this, ...fatherParams);
  this.text = '子类属性';
  this.sonParams = sonParams;
}
// 原型链继承,将`this`和`prototype`声明的属性/方法继承至子类的`prototype`上
Son.prototype = new Father('xxxxx');
var fatherParams = [];
var sonParams = [];
var sonInstance = new Son(fatherParams, ...sonParams);

5.2 优点

1、解决原型链继承父类this声明的属性或者方法被共享的问题。

2、解决借用构造函数解决不能继承父类prototype对象上的属性/方法问题。

5.3 缺点

1、调用了父类函数两次,造成一定的性能问题。

2、因调用两次父类,导出父类通过this声明的属性和方法被生成两份的问题。

3、原型链上下文丢失,子类和父类通过prototype声明的属性和方法都存在与子类prototype上。

六、原型式继承

6.1 实现

function cloneObj(obj) {
  function F(){};
  // 将被继承的对象作为空函数的prototype
  F.prototype = obj;
  // 返回new期间创建的新对象,此对象的原型为被继承的对象,
  // 通过原型链查找可以拿到被继承对象的属性
  return new F();
}

6.2 优点

1、兼容性好,最简单的对象继承。

6.3 缺点

1、多少实例共享被继承的属性,存在被篡改的情况,不能传递参数。

七、寄生式继承(继承过程封装)

创建一个仅用于封装继承过程的函数,改函数在内部已某种方式类增强对象,最后返回对象。在原型式继承的基础上进行增强对象。

7.1 实现

function createAnother(original){
 var clone = cloneObject(original); // 继承一个对象 返回新函数
 // do something 以某种方式来增强对象
 clone.some = function(){}; // 方法
 clone.obkoro1 = '封装继承过程'; // 属性
 return clone; // 返回这个对象
}

7.2 优点

1、兼容性好,最简单的对象继承。

7.3 缺点

1、多少实例共享被继承的属性,存在被篡改的情况,不能传递参数。

八、寄生组合式继承(call+寄生式封装)

1、使用借用构造函数来继承父类this声明的属性和方法。2、使用寄生式继承来设置父类prototype为子类prototype的原型来继承父类的属性和方法。

8.1 实现

function Father(...arr) {
  this.some = '父类属性';
  this.params = arr;
}
Father.prototype.someFn = function() {
  console.log(1);
}
Father.prototype.someValue = '2';
function Son() {
  Father.call(this, 'xxxx');
  this.text = '2222';
}
function inhertPro(son, father){
  // 原型式继承
  var fatherPrototype = Object.create(father.prototype);
  // 设置Son.prototype的原型是Father.prototype
  son.prototype = fatherPrototype;
  // 修正constructor 指向
  // constructor的作用:返回创建实例对象的Object构造函数的引用。
  // 在这里保持constructor指向的一致性
  son.prototype.constructor = son;
}
inhertPro(Son, Father);
var sonInstance = new Son();

8.2 优点

1、寄生组合式继承是当前最成熟的继承方法,也是先也常用的继承方法,在大多数Js框架中都是用这个作为继承方案。

寄生组合式继承相对组合继承的优点:

1、只调用了父类构造函数一次,节约了性能。

2、避免生成了不必要的属性。

3、使用原型式继承保证了原型链上下文不变,子类的prototype只有子类通过prototype声明的属性和方法,父类的prototype只有父类通过prototype声明的属性和方法。

九、ES6-extends继承

9.1 实现

ES6可以用过extends关键字实现继承,这比通过ES5的修改原型链实现继承,要清晰和方法很多。

class Point{}
class ColorPoint extends Point{}

9.2 注意

子类必须在constructor方法中代用super方法,否则新建实例将会报错,这是因为子类自己的this对象,必须先通过父类的构造函数完成塑性,得到父类的属性和方法,然后对其加工,加上子类自己的属性和方法。如果不调用super方法,子类将得不到this对象。如果没有定义constructor方法,这个方法会被默认的添加。

9.3 转换

ES6继承的原理跟寄生组合式继承是一样的。优缺点也相仿。

把ES6的代码装换为ES5 https://www.babeljs.cn/repl

转换前:

class Point{}
class ColorPoint extends Point{}

转换后:

转换的结果核心代码如下:用于子类的prototype继承父类的prototype方法。

function _inherits(subClass, superClass) {
  if (typeof superClass !== "function" && superClass !== null) {
    throw new TypeError("Super expression must either be null or a function");
  }
  subClass.prototype = Object.create(superClass && superClass.prototype, {
    constructor: {
      value: subClass, writable: true, configurable: true 
    }
  });
  if (superClass) _setPrototypeOf(subClass, superClass);
}

9.4 区别

ES5的继承实质是先创建子类的实例对象this,然后将父类的方法添加到this上。

ES6的继承实质是先将父类实例对象的方法和属性加到this上面,然后在用子类的构造函数修改this。

参考

JS基础-深入浅出继承
JavaScript高级程序设计

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • js 按照指定间隔 向字符串中插入随机字符串的实现代码

    js 按照指定间隔 向字符串中插入随机字符串的实现代码

    看到论坛有人问,觉得有意思,就试着写了一下。
    2010-03-03
  • 网站繁简切换的JS遇到页面卡死的解决方法

    网站繁简切换的JS遇到页面卡死的解决方法

    最近开发了繁体版本的网站,在网上找了一段比较流行的繁简切换的JS实现了,不过后来却发现,有些页面会卡死,针对这个问题,下面有个不错的解决方法
    2014-03-03
  • JavaScript实现点击自制菜单效果

    JavaScript实现点击自制菜单效果

    这篇文章主要为大家详细介绍了JavaScript实现点击自制菜单效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-02-02
  • JS+CSS实现仿新浪微博搜索框的方法

    JS+CSS实现仿新浪微博搜索框的方法

    这篇文章主要介绍了JS+CSS实现仿新浪微博搜索框的方法,实例分析了javascript针对搜索框样式的控制技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • ES6顶层对象、global对象实例分析

    ES6顶层对象、global对象实例分析

    这篇文章主要介绍了ES6顶层对象、global对象,结合实例形式分析了ES6顶层对象与global对象的概念、原理、用法及相关操作注意事项,需要的朋友可以参考下
    2019-06-06
  • 微信小程序发布新版本时自动提示用户更新的方法

    微信小程序发布新版本时自动提示用户更新的方法

    这篇文章主要介绍了微信小程序发布新版本时自动提示用户更新的方法,文中通过示例代码介绍的非常详细,对大家学习或者使用小程序具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-06-06
  • webpack开发环境和生产环境的深入理解

    webpack开发环境和生产环境的深入理解

    这篇文章主要介绍了webpack开发环境和生产环境的深入理解,详细的介绍了什么是开发环境和生产环境并配置,非常具有实用价值,需要的朋友可以参考下
    2018-11-11
  • Bootstrap表单组件教程详解

    Bootstrap表单组件教程详解

    表单常见的元素主要包括:文本输入框、下拉选择框、单选框、复选框、文本域、按钮等。接下来通过本文给大家介绍Bootstrap表单组件教程,感兴趣的朋友一起学习吧
    2016-04-04
  • JavaScript在控件上添加倒计时功能的实现代码

    JavaScript在控件上添加倒计时功能的实现代码

    JavaScript在控件上添加倒计时功能,主要原理是利用控件的setEnable(true)/setEnable(false)来进行设置控件的可用与不可用状态,实现过程非常简单,需要的的朋友参考下吧
    2017-07-07
  • JavaScript实现反转字符串的方法详解

    JavaScript实现反转字符串的方法详解

    这篇文章主要介绍了JavaScript实现反转字符串的方法,结合实例形式分析了字符串反转操作,并详细讲述了相关函数的功能与使用注意事项,需要的朋友可以参考下
    2017-04-04

最新评论