集团主站
欢迎来到成都达内官方网站!达内—美国上市公司 亿元级外企IT培训企业!
成都it培训哪家好
成都it培训哪家好
全国服务监督电话:15023458194  |   联系客服   |
当前位置:主页 > 培训课程 > web前端 >

成都前端学习路线-JS的继承,学会面试用!

发布者: 成都达内     浏览次数:     发布时间:2019-03-15 10:23:36

继承对于JS来说就是父类拥有的方法和属性、静态方法等,子类也要拥有。子类中可以利用原型链查找,也可以在子类调用父类,或者从父类拷贝一份到子类等方案。...

  成都前端学习路线-JS的继承,学会面试用!

  用过 React的人都知道,经常用 extends继承 React.Component:

  // 部分源码

  function Component(props, context, updater) {

  // ...

  }

  Component.prototype.setState = function(partialState, callback){

  // ...

  }

  const React = {

  Component,

  // ...

  }

  // 使用

  class index extends React.Component{

  // ...

  }

  面试官可以顺着这个问 JS继承的相关问题,比如: ES6的 class继承用ES5如何实现。据说很多人答得不好。

  构造函数、原型对象和实例之间的关系

  要弄懂extends继承之前,先来复习一下构造函数、原型对象和实例之间的关系。

  代码表示:

  function F(){}

  var f = new F();

  // 构造器

  F.prototype.constructor === F; // true

  F.__proto__ === Function.prototype; // true

  Function.prototype.__proto__ === Object.prototype; // true

  Object.prototype.__proto__ === null; // true

  // 实例

  f.__proto__ === F.prototype; // true

  F.prototype.__proto__ === Object.prototype; // true

  Object.prototype.__proto__ === null; // true

  笔者画了一张图表示:

  成都前端学习路线

  ES6 extends 继承做了什么操作

  我们先看看这段包含静态方法的 ES6继承代码:

  成都前端学习路线

  其中这段代码里有两条原型链,不信看具体代码。

  // 1、构造器原型链

  Child.__proto__ === Parent; // true

  Parent.__proto__ === Function.prototype; // true

  Function.prototype.__proto__ === Object.prototype; // true

  Object.prototype.__proto__ === null; // true

  // 2、实例原型链

  child.__proto__ === Child.prototype; // true

  Child.prototype.__proto__ === Parent.prototype; // true

  Parent.prototype.__proto__ === Object.prototype; // true

  Object.prototype.__proto__ === null; // true

  一图胜千言,笔者也画了一张图表示,如图所示:

  JS的继承

  结合代码和图可以知道, ES6extends 继承,主要就是:

  1、把子类构造函数( Child)的原型( __proto__)指向了父类构造函数( Parent)。

  2、把子类实例 child的原型对象( Child.prototype) 的原型( __proto__)指向了父类 parent的原型对象( Parent.prototype)。 这两点也就是图中用不同颜色标记的两条线。

  3、子类构造函数 Child继承了父类构造函数 Preant的里的属性。使用 super调用的( ES5则用 call或者 apply调用传参)。 也就是图中用不同颜色标记的两条线。

  看过《JavaScript高级程序设计-第3版》 章节 6.3继承的读者应该知道,这2和3小点,正是寄生组合式继承,书中例子没有第1小点。

  1和2小点都是相对于设置了 __proto__链接。那问题来了,什么可以设置 __proto__链接呢。

  设置 proto

  new、 Object.create和 Object.setPrototypeOf可以设置 __proto__。

  说明一下, __proto__这种写法是浏览器厂商自己的实现。

  再结合一下图和代码看一下的 new, new出来的实例的 __proto__指向构造函数的 prototype,这就是 new做的事情。

  new 做了什么

  1、创建了一个全新的对象。

  2、这个对象会被执行 [[Prototype]](也就是 __proto__)链接。

  3、生成的新对象会绑定到函数调用的 this。

  4、通过 new创建的每个对象将最终被 [[Prototype]]链接到这个函数的 prototype对象上。

  5、如果函数没有返回对象类型 Object(包含 Functoin, Array, Date, RegExg, Error),那么 new表达式中的函数调用会自动返回这个新的对象。

  Object.create:ES5提供的

  Object.create(proto,[propertiesObject]) 方法创建一个新对象,使用现有的对象来提供新创建的对象的 __proto__。

  它接收两个参数,不过第二个可选参数是属性描述符(不常用,默认是 undefined)。对于不支持 ES5的浏览器, MDN上提供了 ployfill方案:MDN Object.create()

  // 简版:也正是应用了new会设置__proto__链接的原理。

  if(typeof Object.create !== 'function'){

  Object.create = function(proto){

  function F() {}

  F.prototype = proto;

  return new F();

  }

  }

  Object.setPrototypeOf:ES6提供的

  Object.setPrototypeOf() 方法设置一个指定的对象的原型(即内部 [[Prototype]]属性)到另一个对象或 null: Object.setPrototypeOf(obj,prototype)。

  `ployfill`

  // 仅适用于Chrome和FireFox,在IE中不工作:

  Object.setPrototypeOf = Object.setPrototypeOf || function (obj, proto) {

  obj.__proto__ = proto;

  return obj;

  }

  nodejs源码就是利用这个实现继承的工具函数的。

  inherits(ctor, superCtor) {

  if (ctor === undefined || ctor === null)

  throw new ERR_INVALID_ARG_TYPE('ctor', 'Function', ctor);

  if (superCtor === undefined || superCtor === null)

  throw new ERR_INVALID_ARG_TYPE('superCtor', 'Function', superCtor);

  if (superCtor.prototype === undefined) {

  throw new ERR_INVALID_ARG_TYPE('superCtor.prototype',

  'Object', superCtor.prototype);

  }

  Object.defineProperty(ctor, 'super_', {

  value: superCtor,

  writable: true,

  configurable: true

  });

  Object.setPrototypeOf(ctor.prototype, superCtor.prototype);

  }

  extends的ES5版本实现

  知道了ES6 extends继承做了什么操作和设置 __proto__的知识点后,把上面 ES6例子的用 ES5就比较容易实现了,也就是说实现寄生组合式继承,简版代码就是:

  JS的继承

  我们完全可以把上述 ES6的例子通过 babeljs(https://babeljs.io/repl)转码成 ES5来查看,更严谨的实现。

  成都前端技术培训学校

  成都web前端开发学校

  成都好的前端培训机构

  成都前端学习路线-JS的继承,学会面试用!

  如果对JS继承相关还是不太明白的读者,推荐阅读以下书籍的相关章节,可以自行找到相应的 pdf版本。

  推荐阅读JS继承相关的书籍章节

  1、《JavaScript高级程序设计第3版》第6章——面向对象的程序设计

  6种继承的方案,分别是原型链继承、借用构造函数继承、组合继承、原型式继承、寄生式继承、寄生组合式继承。图灵社区本书地址,后文放出 github链接,里面包含这几种继承的代码 demo。

  2、《JavaScript面向对象编程第2版》第6章——继承

  12种继承的方案:

  原型链法(仿传统)

  仅从原型继承法

  临时构造器法

  原型属性拷贝法

  全属性拷贝法(即浅拷贝法)

  深拷贝法

  原型继承法

  扩展与增强模式

  多重继承法

  寄生继承法

  构造器借用法

  构造器借用与属性拷贝法

  总结

  继承对于JS来说就是父类拥有的方法和属性、静态方法等,子类也要拥有。子类中可以利用原型链查找,也可以在子类调用父类,或者从父类拷贝一份到子类等方案。

  继承方法可以有很多,重点在于必须理解并熟。

  悉这些对象、原型以及构造器的工作方式,剩下的就简单了。寄生组合式继承是开发者使用比较多的。

  回顾寄生组合式继承,主要就是三点:

  子类构造函数的 __proto__指向父类构造器,继承父类的静态方法

  子类构造函数的 prototype的 __proto__指向父类构造器的 prototype,继承父类的方法。

  子类构造器里调用父类构造器,继承父类的属性。

  行文到此,文章就基本写完了。文章代码和图片等资源放在这里github inhert和 demo展示 es6-extends,结合 console、 source面板查看更佳。

(责任编辑:范老师)
最新开班
  • 成都Java培训班
    免费试听名额发放中...
  • 成都C++培训班
    免费试听名额发放中...
  • 成都PHP培训班
    免费试听名额发放中...
  • 成都网络工程培训班
    免费试听名额发放中...
  • 成都Unity3D培训班
    免费试听名额发放中...
  • 成都大数据培训班
    免费试听名额发放中...
  • 成都uid培训班
    免费试听名额发放中...
  • 成都会计培训班
    免费试听名额发放中...
  • 成都Python培训班
    免费试听名额发放中...
  • 成都嵌入式培训班
    免费试听名额发放中...
  • 成都web培训班
    免费试听名额发放中...
  • 成都软件测试培训班
    免费试听名额发放中...
在线留言
提交

校区地址:绵阳市涪城区临园路东段68号富临大都会7栋3单元9层12号

联系电话:15023458194

公交路线:富乐路口凯德广场(10路;29路;3路;15路;11路;15a路;71路)

校区地址:成都市锦江区东大街紫东楼端35号明宇金融广场19楼1906室

联系电话:15023458194

公交路线:芷泉街(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:成都市高新区奥克斯广场蜀锦路209号一楼商铺

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

校区地址:成都锦江区东大街芷泉街229号东方广场C座3楼303

联系电话:15023458194

公交路线:芷泉街(188路;115路;515路;236路;505路;501路;84路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:成都市武侯区佳灵路3号红牌楼广场2号写字楼11楼1115号

联系电话:15023458194

公交路线:红牌楼东(11路;92路;100路;111路;139路;g28路;快速公交K1/K2) 地铁路线:红牌楼站(地铁3号线)

校区地址:成都市锦江区红星路二段70号四川日报大厦502-2

联系电话:15023458194

公交路线:市二医院站(6路;49路;102路;5路;37路;g92路;) 地铁路线:地铁市二医院(地铁3号线)

校区地址:成都市锦江区东大街芷泉段229号东方广场C座16层

联系电话:15023458194

公交路线:芷泉街(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:东门大桥站(地铁2号线)

校区地址:四川省成都市武侯区高新科技孵化园9号园区E座7楼

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

校区地址:成都市人民南路一段86号“城市之心”大厦26楼

联系电话:15023458194

公交路线:成都市人民南路(6路;14路;42路;72路;76路;1010路;)

校区地址:成都市高新区奥克斯广场B座1708

联系电话:15023458194

公交路线:益州大道锦城大道口(18路;21路;43路;48路;104路;152路;335路 ) 地铁路线:孵化园(地铁1号线)

了解达内动态
关注成都达内教育公众号

首页 | 关于达内 | 课程中心 | 专家师资 | 视频教程 | 学员空间 | 校企合作 | 新闻资讯 | 就业指导 | 网站地图

2016-2025 达内时代科技集团有限公司 版权所有 京ICP证8000853号-56