亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

在使用es6語(yǔ)法class的時(shí)候,babel到底做了什么?

時(shí)飛 / 2015人閱讀

摘要:正常情況,的返回值就是一個(gè)對(duì)象,其實(shí)也就是對(duì)象。好了,上面算是基本說(shuō)清楚了使用語(yǔ)法定義類(lèi)繼承類(lèi),到底發(fā)生了什么,如果錯(cuò)誤,還請(qǐng)指正,謝謝

自從有了webpack之后,我們這些jscoder似乎得到了前所未有的解放,箭頭函數(shù),對(duì)象解構(gòu),let,const關(guān)鍵字,以及class、extends等等關(guān)鍵字使用得不亦樂(lè)乎,反正,webpack會(huì)幫我們把這些es6代碼轉(zhuǎn)換成瀏覽器能夠識(shí)別的es5代碼,那么,我們有多少人真正的看過(guò),babel轉(zhuǎn)換之后的代碼呢?今天,我就來(lái)看一下,當(dāng)我們使用關(guān)鍵詞class的時(shí)候,babel到底做了什么?

1、打開(kāi)網(wǎng)址:https://babeljs.io/repl

我推薦打開(kāi)網(wǎng)址:https://babeljs.io/repl,這里我們左邊寫(xiě)es6代碼,馬上右邊就能轉(zhuǎn)譯出es5代碼,然后,我在左邊輸入了如下代碼:

class A {
  constructor(name) {
      this.name = name
  }
  
  getName() {
      return this.name
  }
}

這是一個(gè)最簡(jiǎn)單的類(lèi),一個(gè)屬性,一個(gè)方法。

這時(shí)候,右邊框已經(jīng)給我轉(zhuǎn)譯出了瀏覽器可識(shí)別的es5代碼了,格式化之后是這樣的:

"use strict";

var _createClass = function () {
    function defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
            var descriptor = props[i];
            descriptor.enumerable = descriptor.enumerable || false;
            descriptor.configurable = true;
            if ("value" in descriptor) descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }

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

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

var A = function () {
    function A(name) {
        _classCallCheck(this, A);

        this.name = name;
    }

    _createClass(A, [{
        key: "getName",
        value: function getName() {
            return this.name;
        }
    }]);

    return A;
}();

好,現(xiàn)在來(lái)分析一下這段代碼。

2、es6里面的類(lèi),本質(zhì)上其實(shí)就是一個(gè)函數(shù)
// 自執(zhí)行函數(shù)
var A = function () {
    function A(name) {
        // 這個(gè)函數(shù)的目的其實(shí)是防止這個(gè)構(gòu)造函數(shù)被當(dāng)做普通函數(shù)執(zhí)行
        _classCallCheck(this, A);
        
        this.name = name;
    }

    // 對(duì)函數(shù)A執(zhí)行_createClass方法,其實(shí)就是給A的原型上綁定方法
    _createClass(A, [{
        key: "getName", //方法名
        value: function getName() { //函數(shù)體
            return this.name;
        }
    }]);

    return A;
}();

這段代碼,變量A是一個(gè)自執(zhí)行函數(shù)的返回值,該自執(zhí)行函數(shù)的返回值其實(shí)就是我們熟悉的構(gòu)造函數(shù),所以,es6里面的類(lèi)其實(shí)就是一個(gè)構(gòu)造函數(shù)。

3、_classCallCheck函數(shù)
function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
        throw new TypeError("Cannot call a class as a function");
    }
}

這個(gè)函數(shù)特別簡(jiǎn)單,當(dāng)執(zhí)行函數(shù)A的時(shí)候,不允許this不是A的子類(lèi)實(shí)例,比如直接這樣調(diào)用A(),但是在A的子類(lèi)B中可以這樣調(diào)用:A.apply(this, arguments)。
該函數(shù)的目的是防止構(gòu)造函數(shù)被當(dāng)做普通函數(shù)執(zhí)行。

4、_createClass函數(shù)
//該函數(shù)也是一個(gè)自執(zhí)行的函數(shù),其返回值是一個(gè)函數(shù)
var _createClass = function () {
    // 把props數(shù)組上每一個(gè)對(duì)象,通過(guò)Object.defineProperty方法,都定義到目標(biāo)對(duì)象target上去
    function defineProperties(target, props) {
        for (var i = 0; i < props.length; i++) {
            //這里要確保props[i]是一個(gè)對(duì)象,并且有key和value兩個(gè)鍵
            var descriptor = props[i];
            // 定義是否可以從原型上訪(fǎng)問(wèn)
            descriptor.enumerable = descriptor.enumerable || false;
            // 定義其是否可刪除
            descriptor.configurable = true;
            // 定義該屬性是否可寫(xiě)
            if ("value" in descriptor) descriptor.writable = true;
            Object.defineProperty(target, descriptor.key, descriptor);
        }
    }

    return function (Constructor, protoProps, staticProps) {
        // 如果傳入了原型屬性數(shù)組,就把屬性全部定義到Constructor的原型上去
        if (protoProps) defineProperties(Constructor.prototype, protoProps);
        // 如果傳入了靜態(tài)屬性數(shù)組,就把屬性全部定義到Constructor對(duì)象自身上去
        if (staticProps) defineProperties(Constructor, staticProps);
        return Constructor;
    };
}();

其實(shí)_createClass函數(shù)做的事情,就是把幾個(gè)方法拷貝到構(gòu)造函數(shù)A的原型上去。

4、使用關(guān)鍵詞extends,發(fā)生了什么?

我在https://babeljs.io/repl 左側(cè)輸入框上加了下面這行代碼:

 class B extends A {}

這時(shí)候,右側(cè)多出了以下幾行代碼:

function _possibleConstructorReturn(self, call) {
    if (!self) {
        throw new ReferenceError("this hasn"t been initialised - super() hasn"t been called");
    }
    return call && (typeof call === "object" || typeof call === "function") ? call : self;
}

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

var B = function (_A) {
    _inherits(B, _A);

    function B() {
        _classCallCheck(this, B);
        //這里的重點(diǎn)是第二個(gè)參數(shù):(B.__proto__ || Object.getPrototypeOf(B)).apply(this, arguments);
        //這里其實(shí)是將子類(lèi)的實(shí)例對(duì)象,調(diào)用了父類(lèi)的構(gòu)造函數(shù)方法,這樣父類(lèi)的屬性就都可以拷貝到子類(lèi)上來(lái)
        return _possibleConstructorReturn(this, (B.__proto__ || Object.getPrototypeOf(B)).apply(this, arguments));
    }

    return B;
}(A);
5、_inherits函數(shù)
function _inherits(subClass, superClass) {
    //簡(jiǎn)單校驗(yàn)
    if (typeof superClass !== "function" && superClass !== null) {
        throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
    }
    //把子類(lèi)的原型指向父類(lèi)的原型創(chuàng)建出來(lái)的對(duì)象(注意不是直接指向父類(lèi)原型),并且修正constructor屬性為子類(lèi)自己
    subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: {
            value: subClass,
            enumerable: false,
            writable: true,
            configurable: true
        }
    });
    // 這一步操作,其實(shí)是想把superClass放到subClass下,相當(dāng)于subClass.super = superClass,這樣后面的代碼中,subClass里面能方便的引用到superClass函數(shù)
    if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
6、_possibleConstructorReturn函數(shù)
function _possibleConstructorReturn(self, call) {
    if (!self) {
        throw new ReferenceError("this hasn"t been initialised - super() hasn"t been called");
    }
    return call && (typeof call === "object" || typeof call === "function") ? call : self;
}

如果call不是對(duì)象或者函數(shù),即該調(diào)用:(B.__proto__ || Object.getPrototypeOf(B)).apply(this, arguments)的返回值既不是對(duì)象,也不是函數(shù),那么,就直接返回當(dāng)前的self,而self其實(shí)就是子類(lèi)B里面的實(shí)例指針this。正常情況,(B.__proto__ || Object.getPrototypeOf(B)).apply(this, arguments)的返回值就是一個(gè)對(duì)象,其實(shí)也就是對(duì)象。

好了,上面算是基本說(shuō)清楚了使用es6語(yǔ)法定義類(lèi)、繼承類(lèi),到底發(fā)生了什么,如果錯(cuò)誤,還請(qǐng)指正,謝謝!

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/107871.html

相關(guān)文章

  • Tree-Shaking并沒(méi)什么卵用

    摘要:升級(jí)之后,項(xiàng)目的壓縮包并沒(méi)有什么明顯變化。這里可以參考下阮老師介紹的基本語(yǔ)法的循環(huán)是通過(guò)遍歷器迭代的,循環(huán)數(shù)組時(shí)并非是,然后通過(guò)下標(biāo)尋值。樓主好奇為什么不能消除未引用的類(lèi)。樓主我的代碼沒(méi)什么副作用啊。 本文將探討tree-shaking在當(dāng)下(webpack@3, babel@6 以下)的現(xiàn)狀,以及研究為什么tree-shaking依舊舉步維艱的原因,最終總結(jié)當(dāng)下能提高tree-sha...

    cncoder 評(píng)論0 收藏0
  • babel 到底將代碼轉(zhuǎn)換成什么鳥(niǎo)樣?

    摘要:大概就是將對(duì)象里面的一些屬性轉(zhuǎn)換成數(shù)組,方便解構(gòu)賦值的進(jìn)行。而則更貼近的寫(xiě)法,性能更好一些,兼容性更好一些,但將這部份代碼再轉(zhuǎn)換成的話(huà)會(huì)比較麻煩一些感覺(jué)這一點(diǎn)并不是缺點(diǎn),有源碼就可以了。上面解決的辦法,實(shí)質(zhì)就是將改成。 原文鏈接:https://github.com/lcxfs1991/blog/issues/9 前言 將babel捧作前端一個(gè)劃時(shí)代的工具一定也不為過(guò),它的出現(xiàn)讓許多程...

    qc1iu 評(píng)論0 收藏0
  • 【翻譯】深入理解ES6模塊

    摘要:你可能認(rèn)為和它的新模塊系統(tǒng)出現(xiàn)得有點(diǎn)晚。聚合模塊有時(shí)候一個(gè)包的主模塊只不過(guò)是導(dǎo)入包其他所有的模塊,并用統(tǒng)一的方式導(dǎo)出。靜態(tài)動(dòng)態(tài),或者說(shuō)規(guī)則如何打破規(guī)則作為一個(gè)動(dòng)態(tài)編譯語(yǔ)言,令人驚奇的是擁有一個(gè)靜態(tài)的模塊系統(tǒng)。 回想2007年,那時(shí)候我剛加入Mozillas JavaScript團(tuán)隊(duì),那時(shí)候的一個(gè)典型的JavaScript程序只需要一行代碼,聽(tīng)起來(lái)像個(gè)笑話(huà)。 兩年后,Google Map...

    icattlecoder 評(píng)論0 收藏0
  • 我他喵到底要怎樣才能生產(chǎn)環(huán)境中用上 ES6 模塊化?

    摘要:因此,你還是需要各種各樣雜七雜八的工具來(lái)轉(zhuǎn)換你的代碼噢,我可去你媽的吧,這些東西都是干嘛的我就是想用個(gè)模塊化,我到底該用啥子本文正旨在列出幾種可用的在生產(chǎn)環(huán)境中放心使用模塊化的方法,希望能幫到諸位后來(lái)者這方面的中文資源實(shí)在是忒少了。 原文發(fā)表在我的博客上。最近搗鼓了一下 ES6 的模塊化,分享一些經(jīng)驗(yàn) :) Python3 已經(jīng)發(fā)布了九年了,Python 社區(qū)卻還在用 Python 2...

    KaltZK 評(píng)論0 收藏0
  • 揭秘babel魔法之class繼承處理2

    摘要:并且用驗(yàn)證了中一系列的實(shí)質(zhì)就是魔法糖的本質(zhì)。抽絲剝繭我們首先看的編譯結(jié)果這是一個(gè)自執(zhí)行函數(shù),它接受一個(gè)參數(shù)就是他要繼承的父類(lèi),返回一個(gè)構(gòu)造函數(shù)。 如果你已經(jīng)看過(guò)第一篇揭秘babel的魔法之class魔法處理,這篇將會(huì)是一個(gè)延伸;如果你還沒(méi)看過(guò),并且也不想現(xiàn)在就去讀一下,單獨(dú)看這篇也沒(méi)有關(guān)系,并不存在理解上的障礙。 上一篇針對(duì)Babel對(duì)ES6里面基礎(chǔ)class的編譯進(jìn)行了分析。這一篇將...

    BlackHole1 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<