国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

ES6類以及繼承的實(shí)現(xiàn)原理

Warren / 1352人閱讀

摘要:中通過(guò)關(guān)鍵字,定義類經(jīng)過(guò)轉(zhuǎn)碼之后可以看到類的底層還是通過(guò)構(gòu)造函數(shù)去創(chuàng)建的。在中,構(gòu)造函數(shù)是可以直接運(yùn)行的,比如。如果你有靜態(tài)屬性,會(huì)直接添加到構(gòu)造函數(shù)上。不是很好理解,可以通過(guò)下面的方式理解是一個(gè)實(shí)例,是構(gòu)造方法的原型。

ES6中通過(guò)class關(guān)鍵字,定義類

class Parent {
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    speakSomething(){
        console.log("I can speek chinese");
    }
}

經(jīng)過(guò)babel轉(zhuǎn)碼之后

"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 Parent = function () {
    function Parent(name, age) {
        _classCallCheck(this, Parent);

        this.name = name;
        this.age = age;
    }

    _createClass(Parent, [{
        key: "speakSomething",
        value: function speakSomething() {
            console.log("I can speek chinese");
        }
    }]);

    return Parent;
}();

可以看到ES6類的底層還是通過(guò)構(gòu)造函數(shù)去創(chuàng)建的。

通過(guò)ES6創(chuàng)建的類,是不允許你直接調(diào)用的。在ES5中,構(gòu)造函數(shù)是可以直接運(yùn)行的,比如Parent()。但是在ES6就不行。我們可以看到轉(zhuǎn)碼的構(gòu)造函數(shù)中有_classCallCheck(this, Parent)語(yǔ)句,這句話是防止你通過(guò)構(gòu)造函數(shù)直接運(yùn)行的。你直接在ES6運(yùn)行Parent(),這是不允許的,ES6中拋出Class constructor Parent cannot be invoked without "new"錯(cuò)誤。轉(zhuǎn)碼后的會(huì)拋出Cannot call a class as a function.我覺(jué)得這樣的規(guī)范挺好的,能夠規(guī)范化類的使用方式。

轉(zhuǎn)碼中_createClass方法,它調(diào)用Object.defineProperty方法去給新創(chuàng)建的Parent添加各種屬性。defineProperties(Constructor.prototype, protoProps)是給原型添加屬性。如果你有靜態(tài)屬性,會(huì)直接添加到構(gòu)造函數(shù)上defineProperties(Constructor, staticProps)。但是貌似并沒(méi)有用到,下面可以證明.

這兩個(gè)流程走下來(lái),其實(shí)就創(chuàng)建了一個(gè)類。

上面講的是創(chuàng)建一個(gè)類的過(guò)程,那ES6如何實(shí)現(xiàn)繼承的呢?還是上面的例子,這次我們給Parent添加靜態(tài)屬性,原型屬性,內(nèi)部屬性

class Parent {
    static height = 12
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
    speakSomething(){
        console.log("I can speek chinese");
    }
}
Parent.prototype.color = "yellow"


//定義子類,繼承父類
class Child extends Parent {
    static width = 18
    constructor(name,age){
        super(name,age);
    }
    coding(){
        console.log("I can code JS");
    }
}

var c = new Child("job",30);
c.coding()

轉(zhuǎn)碼之后的代碼變成了這樣

"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 _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;
}

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

var Parent = function () {
    function Parent(name, age) {
        _classCallCheck(this, Parent);

        this.name = name;
        this.age = age;
    }

    _createClass(Parent, [{
        key: "speakSomething",
        value: function speakSomething() {
            console.log("I can speek chinese");
        }
    }]);

    return Parent;
}();

Parent.height = 12;

Parent.prototype.color = "yellow";

//定義子類,繼承父類

var Child = function (_Parent) {
    _inherits(Child, _Parent);

    function Child(name, age) {
        _classCallCheck(this, Child);

        return _possibleConstructorReturn(this, (Child.__proto__ || Object.getPrototypeOf(Child)).call(this, name, age));
    }

    _createClass(Child, [{
        key: "coding",
        value: function coding() {
            console.log("I can code JS");
        }
    }]);

    return Child;
}(Parent);

Child.width = 18;


var c = new Child("job", 30);
c.coding();

我們可以看到,構(gòu)造類的方法都沒(méi)變,只是添加了_inherits核心方法來(lái)實(shí)現(xiàn)繼承,下面我們就看下這個(gè)方法做了什么?

首先是判斷父類的類型,然后

subClass.prototype = Object.create(superClass && superClass.prototype, {
        constructor: {
            value: subClass,
            enumerable: false,
            writable: true,
            configurable: true
        }
    });

這段代碼翻譯下來(lái)就是

function F(){}
F.prototype = superClass.prototype
subClass.prototype = new F()
subClass.prototype.constructor = subClass

接下來(lái)subClass.__proto__ = superClass
_inherits核心思想就是下面兩句

subClass.prototype.__proto__ = superClass.prototype
subClass.__proto__ = superClass

一圖勝千言

那為什么這樣一倒騰,它就實(shí)現(xiàn)了繼承了呢?
首先 subClass.prototype.__proto__ = superClass.prototype保證了c instanceof Parent是true,Child的實(shí)例可以訪問(wèn)到父類的屬性,包括內(nèi)部屬性,以及原型屬性。其次,subClass.__proto__ = superClass,保證了Child.height也能訪問(wèn)到,也就是靜態(tài)方法。

subClass.__proto__ = superClass不是很好理解,可以通過(guò)下面的方式理解

function A(){}
var a = new A()
a.__proto__ = A.prototype

a是一個(gè)實(shí)例,A.prototype是構(gòu)造方法的原型。通過(guò)這種方式,那么a就可以訪問(wèn)A.prototype上面的方法。

那把 subClass類比成 a,superClass類比成A.prototype,那是不是subClass可以直接訪問(wèn) superClass的靜態(tài)屬性,靜態(tài)方法了。

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/94848.html

相關(guān)文章

  • javascript之模擬繼承

    摘要:歡迎關(guān)注我的博客正文讓我來(lái)構(gòu)造函數(shù)其實(shí),模擬一個(gè)類的方式非常的簡(jiǎn)單構(gòu)造函數(shù)。我們先來(lái)看一個(gè)例子這里通過(guò)構(gòu)造函數(shù)模擬出來(lái)的類,其實(shí)和其他語(yǔ)言的類行為上是基本一致的,唯一的區(qū)別就是它不具備私有方法。 前言 ES6時(shí)代的來(lái)臨,使得類繼承變得如此的圓滑。但是,你有思考過(guò)ES6的類繼承模式嗎?如何去實(shí)現(xiàn)它呢? 類繼承對(duì)于JavaScript來(lái)說(shuō),實(shí)現(xiàn)方式與Java等類語(yǔ)言大不相同。熟悉JavaS...

    Jochen 評(píng)論0 收藏0
  • es6繼承實(shí)現(xiàn)原理

    摘要:類的實(shí)現(xiàn)轉(zhuǎn)換前轉(zhuǎn)換后可見(jiàn)的底層依然是構(gòu)造函數(shù)調(diào)用方法判斷當(dāng)前函數(shù)調(diào)用前是否有關(guān)鍵字。若構(gòu)造函數(shù)前面沒(méi)有則構(gòu)造函數(shù)的不會(huì)不出現(xiàn)在的原型鏈上,返回。典型的寄生繼承用父類構(gòu)造函數(shù)的創(chuàng)建一個(gè)空對(duì)象,并將這個(gè)對(duì)象指向子類構(gòu)造函數(shù)的。代表父類構(gòu)造函數(shù)。 在閱讀文章之前,您至少需要對(duì)JavaScript原型繼承有一定了解,如果覺(jué)得有所欠缺,可以先了解下我這篇文章:https://segmentfau...

    haitiancoder 評(píng)論0 收藏0
  • JavaScript是如何工作:深入繼承內(nèi)部原理+Babel和 TypeScript 之間轉(zhuǎn)換

    摘要:下面是用實(shí)現(xiàn)轉(zhuǎn)成抽象語(yǔ)法樹(shù)如下還支持繼承以下是轉(zhuǎn)換結(jié)果最終的結(jié)果還是代碼,其中包含庫(kù)中的一些函數(shù)。可以使用新的易于使用的類定義,但是它仍然會(huì)創(chuàng)建構(gòu)造函數(shù)和分配原型。 這是專門(mén)探索 JavaScript 及其所構(gòu)建的組件的系列文章的第 15 篇。 想閱讀更多優(yōu)質(zhì)文章請(qǐng)猛戳GitHub博客,一年百來(lái)篇優(yōu)質(zhì)文章等著你! 如果你錯(cuò)過(guò)了前面的章節(jié),可以在這里找到它們: JavaScript 是...

    PrototypeZ 評(píng)論0 收藏0
  • 高級(jí)前端面試題大匯總(只有試題,沒(méi)有答案)

    摘要:面試題來(lái)源于網(wǎng)絡(luò),看一下高級(jí)前端的面試題,可以知道自己和高級(jí)前端的差距。 面試題來(lái)源于網(wǎng)絡(luò),看一下高級(jí)前端的面試題,可以知道自己和高級(jí)前端的差距。有些面試題會(huì)重復(fù)。 使用過(guò)的koa2中間件 koa-body原理 介紹自己寫(xiě)過(guò)的中間件 有沒(méi)有涉及到Cluster 介紹pm2 master掛了的話pm2怎么處理 如何和MySQL進(jìn)行通信 React聲明周期及自己的理解 如何...

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

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

0條評(píng)論

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