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


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 相关文章推荐
JavaScript操作XML实例代码(获取新闻标题并分页,并分页)
May 25 Javascript
基于jquery实现的鼠标滑过按钮改变背景图片
Jul 15 Javascript
IE6下focus与blur错乱的解决方案
Jul 31 Javascript
JavaScript高级程序设计(第3版)学习笔记 概述
Oct 11 Javascript
解决jquery异步按一定的时间间隔刷新问题
Dec 10 Javascript
js、css、img等浏览器缓存问题的2种解决方案
Oct 23 Javascript
跨域传值即主页面与iframe之间互相传值
Dec 09 Javascript
jQuery中nextAll()方法用法实例
Jan 07 Javascript
javascript实现点击商品列表checkbox实时统计金额的方法
May 15 Javascript
jquery实现无刷新验证码的简单实例
May 19 Javascript
js实现弹窗居中的简单实例
Oct 09 Javascript
JS实现的简单标签点击切换功能示例
Sep 21 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
php addslashes和mysql_real_escape_string
2010/01/24 PHP
PHP生成器简单实例
2015/05/13 PHP
php实现数组重复数字统计实例
2018/09/30 PHP
JQuery jsonp 使用示例代码
2009/08/12 Javascript
Javascript 设计模式(二) 闭包
2010/05/26 Javascript
javascript针对DOM的应用分析(四)
2012/04/15 Javascript
javascript当中的代码嗅探扩展原生对象和原型(prototype)
2013/01/11 Javascript
javascript自适应宽度的瀑布流实现思路
2013/02/20 Javascript
jquery定时滑出可最小化的底部提示层特效代码
2013/10/02 Javascript
Javascript玩转继承(一)
2014/05/08 Javascript
JavaScript组合拼接字符串的效率对比测试
2014/11/06 Javascript
js给selected添加options的方法
2015/05/06 Javascript
js实现鼠标移到链接文字弹出一个提示层的方法
2015/05/11 Javascript
Struts2+jquery.form.js实现图片与文件上传的方法
2016/05/05 Javascript
laypage分页控件使用实例详解
2016/05/19 Javascript
AngularJS HTML DOM详解及示例代码
2016/08/17 Javascript
微信小程序 参数传递实例代码
2017/03/20 Javascript
vue中mint-ui环境搭建详细介绍
2017/04/06 Javascript
微信小程序制作表格的方法
2019/02/14 Javascript
小程序新版订阅消息模板消息
2019/12/31 Javascript
jQuery实现可以扩展的日历
2020/12/01 jQuery
一行JavaScript代码如何实现瀑布流布局
2020/12/11 Javascript
[00:13]天涯墨客二技能展示
2018/08/25 DOTA
Python操作Oracle数据库的简单方法和封装类实例
2018/05/07 Python
pandas 对series和dataframe进行排序的实例
2018/06/09 Python
python获取本机所有IP地址的方法
2018/12/26 Python
python字符串查找函数的用法详解
2019/07/08 Python
浅谈pytorch卷积核大小的设置对全连接神经元的影响
2020/01/10 Python
python实现杨辉三角的几种方法代码实例
2021/03/02 Python
介绍下java.util.Arrays类
2012/10/16 面试题
经典毕业生求职信
2014/07/12 职场文书
4s店活动策划方案
2014/08/25 职场文书
创建文明城市倡议书
2015/04/28 职场文书
幼儿园春季开学通知
2015/07/16 职场文书
员工聘用合同范本
2015/09/21 职场文书
解决Mysql多行子查询的使用及空值问题
2022/01/22 MySQL