欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

繼承行為在 ES5 與 ES6 中的區(qū)別詳解

 更新時(shí)間:2019年12月24日 17:03:29   作者:monster1935  
這篇文章主要介紹了繼承行為在 ES5 與 ES6 中的區(qū)別詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

筆者注:一句話引發(fā)的基礎(chǔ)知識(shí)回爐,基礎(chǔ)不扎實(shí),還要什么自行車

最近在看 React 方面的一些文章時(shí),看到了這樣一個(gè)問題,「為什么每個(gè) class 中都要寫 super, super 是做什么的?」, 剛看到這個(gè)問題時(shí),直接就想到了繼承行為在 javascript 中的表現(xiàn)。后面作者的一句話「super 不可以省略,省略的話會(huì)報(bào)錯(cuò)」。當(dāng)時(shí)腦海中蹦出來一個(gè)念頭,這個(gè)同學(xué)是不是寫錯(cuò)了,super 不就是用來完成調(diào)用父類構(gòu)造函數(shù),將父類的實(shí)例屬性掛在到 this 上嗎?為什么不寫還會(huì)報(bào)錯(cuò)?

后來自己親自寫了一個(gè) Demo 嘗試了一下,還真是會(huì)報(bào)錯(cuò),到底是哪里出了問題,找到了阮老師的教程又打開仔細(xì)看了一遍,發(fā)現(xiàn)里面還真是有這樣一句話:

子類必須在 constructor 方法中調(diào)用 super 方法,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò)。這是因?yàn)樽宇愖约旱?this 對(duì)象,必須先通過父類的構(gòu)造函數(shù)完成塑造,得到與父類同樣的實(shí)例屬性和方法,然后再對(duì)其進(jìn)行加工,加上子類自己的實(shí)例屬性和方法。如果不調(diào)用 super 方法,子類就得不到 this 對(duì)象。

原來如此,ES6 中 this 對(duì)象的構(gòu)造方式發(fā)生了變化。

ES5 中的繼承

// Shape - 父類(superclass)
function Shape() {
 this.x = 0;
 this.y = 0;
}

// 父類的方法
Shape.prototype.move = function(x, y) {
 this.x += x;
 this.y += y;
 console.info('Shape moved.');
};

// Rectangle - 子類(subclass)
function Rectangle() {
 Shape.call(this); // call super constructor.
}

// 子類續(xù)承父類
Rectangle.prototype = Object.create(Shape.prototype);
Rectangle.prototype.constructor = Rectangle;

var rect = new Rectangle();

console.log('Is rect an instance of Rectangle?',
 rect instanceof Rectangle); // true
console.log('Is rect an instance of Shape?',
 rect instanceof Shape); // true
rect.move(1, 1); // Outputs, 'Shape moved.'

如上所示: 展示了一個(gè) ES5 中實(shí)現(xiàn)單繼承的例子,在《Javascript 高級(jí)程序設(shè)計(jì)》一書中,給這種繼承方式定義為「寄生組合式繼承」。不管什么形式,什么命名,在 ES5 中實(shí)現(xiàn)繼承始終就是要堅(jiān)持一個(gè)原則:將實(shí)例屬性放在構(gòu)造函數(shù)中掛在this上,將一些方法屬性掛在原型對(duì)象上,子類可共享。 上面這種繼承方式的關(guān)鍵在于兩點(diǎn):

  1. 子類構(gòu)造函數(shù)通過 apply 或者 call 的方式運(yùn)行父類的構(gòu)造函數(shù),此舉將父類的實(shí)例屬性掛在子類的 this 對(duì)象上
  2. 以父類的原型對(duì)象為基礎(chǔ),與子類的原型對(duì)象之間建立原型鏈關(guān)系,使用了 Object.create,本質(zhì)在于 Child.prototype.__proto === Parent.prototype;

ES6 中的繼承

class Point {
 constructor(x, y) {
  this.x = x;
  this.y = y;
 }

 toString() {
  return '(' + this.x + ', ' + this.y + ')';
 }
}

class ColorPoint extends Point {
 constructor(x, y, color) {
  super(x, y); // 調(diào)用父類的constructor(x, y)
  this.color = color;
 }

 toString() {
  return this.color + ' ' + super.toString(); 
 }
}

ES6 中的繼承使用到了 extends 關(guān)鍵字,function 也變成了 class 關(guān)鍵字。class 的本質(zhì)還是一個(gè)語(yǔ)法糖,這個(gè)大家都會(huì)脫口而出,但是在繼承機(jī)制這里到底是如何做到的,我們看一下 babel 在此處是如何幫我們轉(zhuǎn)譯的,

var ColorPoint =
/*#__PURE__*/
function (_Point) {
 _inherits(ColorPoint, _Point);

 function ColorPoint(x, y, color) {
  var _this;

  _classCallCheck(this, ColorPoint);

  _this = _possibleConstructorReturn(this, _getPrototypeOf(ColorPoint).call(this, x, y)); // 調(diào)用父類的constructor(x, y)

  _this.color = color;
  return _this;
 }

 _createClass(ColorPoint, [{
  key: "toString",
  value: function toString() {
   return this.color + ' ' + _get(_getPrototypeOf(ColorPoint.prototype), "toString", this).call(this);
  }
 }]);

 return ColorPoint;
}(Point);

如上是經(jīng)過babel轉(zhuǎn)譯后的代碼,有幾個(gè)關(guān)鍵點(diǎn):

一、 _inherits()

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);
}

首先完成extends對(duì)象的校驗(yàn),必須是function 或者null,否則報(bào)錯(cuò)。其次完成以下事情:

ColorPoint.__proto__ === Point;
ColorPoint.prototype.__proto__ === Point.prototype;

二、 ColorPoint 構(gòu)造函數(shù)中 _classCallCheck(), _possibleConstructorReturn()

function _classCallCheck(instance, Constructor) {
 if (!_instanceof(instance, Constructor)) {
   throw new TypeError("Cannot call a class as a function");
 }
}

主要是用來檢測(cè)構(gòu)造函數(shù)不能直接調(diào)用,必須是通過new的方式來調(diào)用。

function _possibleConstructorReturn(self, call) {
 if (call && (_typeof(call) === "object" || typeof call === "function")) {
   return call;
 }
 return _assertThisInitialized(self);
}

調(diào)用父類的構(gòu)造函數(shù),初始化一些實(shí)例屬性,并將this返回。使用該返回的this賦值給子類的this對(duì)象,子類通過這一步返回的this對(duì)象,再該基礎(chǔ)之上在添加一些實(shí)例屬性。

這就是最大的不同之處。如果不經(jīng)歷這一步,子類沒有this對(duì)象,一旦操作一個(gè)不存在的this對(duì)象就會(huì)報(bào)錯(cuò)。

三、 _createClass()

function _createClass(Constructor, protoProps, staticProps) {
 if (protoProps) _defineProperties(Constructor.prototype, protoProps);
 if (staticProps) _defineProperties(Constructor, staticProps);
 return Constructor;
}

最后一步完成原型屬性與靜態(tài)屬性的掛載,如果是原型屬性,掛在在Constructor上的prototype上,如果是靜態(tài)屬性或者靜態(tài)方法,則掛在Constuctor 上。

總結(jié)

基礎(chǔ)知識(shí)要打牢,不是為了面試,前期打不勞,后面很多事情就會(huì)變的模棱兩可,別人問到的時(shí)候,就會(huì)是「可能」、「也許」。不積跬步何以至千里 ,加油。

參考鏈接

http://es6.ruanyifeng.com/#docs/class-extends

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create

https://babeljs.io/repl/#?babili=false&evaluate=true&lineWrap=false&presets=es2015%2Creact%2Cstage-2&targets=&browsers=&builtIns=false&debug=false&code_lz=Q

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 在原生不支持的舊環(huán)境中添加兼容的Object.keys實(shí)現(xiàn)方法

    在原生不支持的舊環(huán)境中添加兼容的Object.keys實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄谠恢С值呐f環(huán)境中添加兼容的Object.keys實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • 微信小程序適配iphoneX的實(shí)現(xiàn)方法

    微信小程序適配iphoneX的實(shí)現(xiàn)方法

    這篇文章主要介紹了微信小程序適配iphoneX的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-09-09
  • JS+CSS 制作的超級(jí)簡(jiǎn)單的下拉菜單附圖

    JS+CSS 制作的超級(jí)簡(jiǎn)單的下拉菜單附圖

    下拉菜單想必大家都有見到過吧,在本文將為大家介紹個(gè)不錯(cuò)的示例,超簡(jiǎn)單的,大家可以參考下哦
    2013-11-11
  • Bootstrap Modal遮罩彈出層(完整版)

    Bootstrap Modal遮罩彈出層(完整版)

    Bootstrap modal是給外層添加固定fixed,然后內(nèi)容使用自適應(yīng)靠上居中方式。今天分享的這篇文章正是這種方式,感興趣的朋友一起看看吧
    2016-11-11
  • 深入了解JavaScript 防抖和節(jié)流

    深入了解JavaScript 防抖和節(jié)流

    這篇文章主要介紹了JavaScript 防抖和節(jié)流,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • javascript自適應(yīng)寬度的瀑布流實(shí)現(xiàn)思路

    javascript自適應(yīng)寬度的瀑布流實(shí)現(xiàn)思路

    這里主要介紹瀑布流的一種實(shí)現(xiàn)方法:絕對(duì)定位(css)+javascript+ajax+json。簡(jiǎn)單一點(diǎn)如果不做滾動(dòng)加載的話就是絕對(duì)定位(css)+javascript了,ajax和json是滾動(dòng)加載更多內(nèi)容的時(shí)候用到的,感興趣的你可以參考下哦
    2013-02-02
  • javascript實(shí)現(xiàn)倒計(jì)時(shí)跳轉(zhuǎn)頁(yè)面

    javascript實(shí)現(xiàn)倒計(jì)時(shí)跳轉(zhuǎn)頁(yè)面

    本文給大家介紹了如何使用javascript實(shí)現(xiàn)倒計(jì)時(shí)跳轉(zhuǎn)到其他頁(yè)面的方法以及實(shí)現(xiàn)原理,非常的簡(jiǎn)單實(shí)用,有需要的小伙伴可以參考下。
    2016-01-01
  • 使用js獲取地址欄參數(shù)的方法推薦(超級(jí)簡(jiǎn)單)

    使用js獲取地址欄參數(shù)的方法推薦(超級(jí)簡(jiǎn)單)

    下面小編就為大家?guī)硪黄褂胘s獲取地址欄參數(shù)的方法推薦(超級(jí)簡(jiǎn)單)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-06-06
  • JavaScript中的scrollTop詳解(滾動(dòng)到頂部)

    JavaScript中的scrollTop詳解(滾動(dòng)到頂部)

    scrollTop是JavaScript中一個(gè)非常有用且重要的方法,它用于獲取或設(shè)置元素的垂直滾動(dòng)條位置,這篇文章主要給大家介紹了關(guān)于JavaScript中scrollTop詳解(滾動(dòng)到頂部)的相關(guān)資料,需要的朋友可以參考下
    2023-12-12
  • js+css在交互上的應(yīng)用

    js+css在交互上的應(yīng)用

    關(guān)于css應(yīng)用。以前一直認(rèn)為css就是做布局樣式,只能表現(xiàn)頁(yè)面,跟交互是沒關(guān)系的。事實(shí)上也基本不會(huì)往那邊想。
    2010-07-07

最新評(píng)論