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


Posted in Javascript onDecember 10, 2019

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高级程序设计

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

Javascript 相关文章推荐
js获取网页高度(详细整理)
Dec 28 Javascript
jQuery使用cookie与json简单实现购物车功能
Apr 15 Javascript
JS检测页面中哪个HTML标签触发点击事件的方法
Jun 17 Javascript
浅谈js基本数据类型和typeof
Aug 09 Javascript
Bootstrap源码解读导航条(7)
Dec 23 Javascript
AngularJs 常用的过滤器
May 15 Javascript
详解基于Bootstrap+angular的一个豆瓣电影app
Jun 26 Javascript
js编写简单的计时器功能
Jul 15 Javascript
Vue自定义指令上报Google Analytics事件统计的方法
Feb 25 Javascript
vue实现新闻展示页的步骤详解
Apr 11 Javascript
使用apifm-wxapi快速开发小程序过程详解
Aug 05 Javascript
Vue2.0 $set()的正确使用详解
Jul 28 Javascript
jquery实现弹窗(系统提示框)效果
Dec 10 #jQuery
微信小程序 this.triggerEvent()的具体使用
Dec 10 #Javascript
jQuery实现消息弹出框效果
Dec 10 #jQuery
jQuery实现弹出层效果
Dec 10 #jQuery
javascript实现弹出层效果
Dec 10 #Javascript
element表格翻页第2页从1开始编号(后端从0开始分页)
Dec 10 #Javascript
微信小程序实现注册登录功能(表单校验、错误提示)
Dec 10 #Javascript
You might like
destoon二次开发常用数据库操作
2014/06/21 PHP
PHP explode()函数用法讲解
2019/02/15 PHP
Gird事件机制初级读本
2007/03/10 Javascript
Javascript的匿名函数小结
2009/12/31 Javascript
JS获取各种浏览器窗口大小的方法
2014/01/14 Javascript
js 数组去重的四种实用方法
2014/09/09 Javascript
JavaScript的null和undefined区别示例介绍
2014/09/15 Javascript
封装的dialog插件 基于bootstrap模态对话框的简单扩展
2016/08/10 Javascript
利用Javascript仿Excel的数据透视分析功能
2016/09/07 Javascript
JavaScript动态检验密码强度的实现方法
2016/11/09 Javascript
Bootstrap弹出框modal上层的输入框不能获得焦点问题的解决方法
2016/12/13 Javascript
AngularJS实现注册表单验证功能
2017/10/16 Javascript
AngularJS实现图片上传和预览功能的方法分析
2017/11/08 Javascript
VSCode配置react开发环境的步骤
2017/12/27 Javascript
jQuery实现导航样式布局操作示例【可自定义样式布局】
2018/07/24 jQuery
详解mpvue开发小程序小总结
2018/07/25 Javascript
axios向后台传递数组作为参数的方法
2018/08/11 Javascript
vue中组件通信的八种方式(值得收藏!)
2019/08/09 Javascript
JavaScript实现飞舞的泡泡效果
2020/02/07 Javascript
原生javascript中this几种常见用法总结
2020/02/24 Javascript
JavaScript实现手风琴效果
2021/02/18 Javascript
Python 变量类型详解
2018/10/10 Python
python调用java的jar包方法
2018/12/15 Python
Windows上安装tensorflow  详细教程(图文详解)
2020/02/04 Python
Python脚本导出为exe程序的方法
2020/03/25 Python
Python描述数据结构学习之哈夫曼树篇
2020/09/07 Python
Python从MySQL数据库中面抽取试题,生成试卷
2021/01/14 Python
深入剖析webstorage[html5的本地数据处理]
2016/07/11 HTML / CSS
DJI美国:消费类无人机领域的领导者
2018/04/27 全球购物
餐饮加盟计划书
2014/01/10 职场文书
电工工作职责范本
2014/02/22 职场文书
平面设计专业大学生职业规划书
2014/03/12 职场文书
2014年食堂工作总结
2014/11/20 职场文书
小学优秀教师先进事迹材料
2014/12/16 职场文书
田径运动会广播稿
2015/08/19 职场文书
写作指导:怎么书写竞聘演讲稿?
2019/07/04 职场文书