成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

深入理解ES6筆記(九)JS的類(class)

xinhaip / 754人閱讀

摘要:主要知識(shí)點(diǎn)類聲明類表達(dá)式類的重要要點(diǎn)以及類繼承深入理解筆記目錄中的仿類結(jié)構(gòu)在及更早版本中都不存在類。與類最接近的是創(chuàng)建一個(gè)構(gòu)造器,然后將方法指派到該構(gòu)造器的原型上。調(diào)用類構(gòu)造器時(shí)不使用,會(huì)拋出錯(cuò)誤。

主要知識(shí)點(diǎn):類聲明、類表達(dá)式、類的重要要點(diǎn)以及類繼承

《深入理解ES6》筆記 目錄

ES5 中的仿類結(jié)構(gòu)

JS 在 ES5 及更早版本中都不存在類。與類最接近的是:創(chuàng)建一個(gè)構(gòu)造器,然后將方法指派到該構(gòu)造器的原型上。這種方式通常被稱為創(chuàng)建一個(gè)自定義類型:

function PersonType(name) {
    this.name = name;
}
PersonType.prototype.sayName = function() {
    console.log(this.name);
};
let person = new PersonType("Nicholas");
person.sayName(); // 輸出 "Nicholas"
console.log(person instanceof PersonType); // true
console.log(person instanceof Object); // true
類的聲明 基本的類聲明

類聲明以 class 關(guān)鍵字開始,其后是類的名稱;剩余部分的語(yǔ)法看起來就像對(duì)象字面量中的方法簡(jiǎn)寫,并且在方法之間不需要使用逗號(hào):

class PersonClass {
    // 等價(jià)于 PersonType 構(gòu)造器,自有屬性
    constructor(name) {
        this.name = name;
    }
    // 等價(jià)于 PersonType.prototype.sayName
    sayName() {
        console.log(this.name);
    }
}
let person = new PersonClass("Nicholas");
person.sayName(); // 輸出 "Nicholas"
console.log(person instanceof PersonClass); // true
console.log(person instanceof Object); // true
console.log(typeof PersonClass); // "function"
console.log(typeof PersonClass.prototype.sayName); // "function"
類聲明和函數(shù)聲明的區(qū)別和特點(diǎn)

類聲明不會(huì)被提升,這與函數(shù)定義不同。類聲明的行為與 let 相似,因此在程序的執(zhí)行到達(dá)聲明處之前,類會(huì)存在于暫時(shí)性死區(qū)內(nèi)。

類聲明中的所有代碼會(huì)自動(dòng)運(yùn)行在嚴(yán)格模式下,并且也無法退出嚴(yán)格模式。

類的所有方法都是不可枚舉的,這是對(duì)于自定義類型的顯著變化,后者必須用Object.defineProperty() 才能將方法改變?yōu)椴豢擅杜e。

類的所有方法內(nèi)部都沒有 [[Construct]] ,因此使用 new 來調(diào)用它們會(huì)拋出錯(cuò)誤。

調(diào)用類構(gòu)造器時(shí)不使用 new ,會(huì)拋出錯(cuò)誤。

試圖在類的方法內(nèi)部重寫類名,會(huì)拋出錯(cuò)誤。

用ES5實(shí)現(xiàn)剛才的類的功能:

// 直接等價(jià)于 PersonClass
let PersonType2 = (function() {
    "use strict";
    //確保在類的內(nèi)部不可以重寫類名
    const PersonType2 = function(name) {
    // 確認(rèn)函數(shù)被調(diào)用時(shí)使用了 new
        if (typeof new.target === "undefined") {
            throw new Error("Constructor must be called with new.");
        }
        this.name = name;
    }
    Object.defineProperty(PersonType2.prototype, "sayName", {
     value: function() {
        // 確認(rèn)函數(shù)被調(diào)用時(shí)沒有使用 new
        if (typeof new.target !== "undefined") {
            throw new Error("Method cannot be called with new.");
        }
        console.log(this.name);
    },
    //定義為不可枚舉
    enumerable: false,
    writable: true,
    configurable: true
    });
    return PersonType2;
}());

此例說明了盡管不使用新語(yǔ)法也能實(shí)現(xiàn)類的任何特性,但類語(yǔ)法顯著簡(jiǎn)化了所有功能的代碼。

類表達(dá)式

類與函數(shù)有相似之處,即它們都有兩種形式:聲明與表達(dá)式。

//聲明式
class B {
  constructor() {}
}

//匿名表達(dá)式
let PersonClass = class {
    // 等價(jià)于 PersonType 構(gòu)造器
    constructor(name) {
    this.name = name;
    }
    // 等價(jià)于 PersonType.prototype.sayName
    sayName() {
        console.log(this.name);
    }
};
let person = new PersonClass("Nicholas");
person.sayName(); // 輸出 "Nicholas"
console.log(person instanceof PersonClass); // true
console.log(person instanceof Object); // true
console.log(typeof PersonClass); // "function"
console.log(typeof PersonClass.prototype.sayName); // "function"

//命名表達(dá)式,B可以在外部使用,而B1只能在內(nèi)部使用
let PersonClass = class PersonClass2 {
    // 等價(jià)于 PersonType 構(gòu)造器
        constructor(name) {
    this.name = name;
    }
    // 等價(jià)于 PersonType.prototype.sayName
    sayName() {
        console.log(this.name);
    }
};
console.log(typeof PersonClass); // "function"
console.log(typeof PersonClass2); // "undefined",只有在類內(nèi)部才可以訪問到
作為一級(jí)公民的類

在編程中,能被當(dāng)作值來使用的就稱為一級(jí)公民( first-class citizen ),意味著它能作為參數(shù)傳給函數(shù)、能作為函數(shù)返回值、能用來給變量賦值。
作為參數(shù)傳入函數(shù):

function createObject(classDef) {
    return new classDef();
}
let obj = createObject(class {
    sayHi() {
        console.log("Hi!");
    }
});
obj.sayHi(); // "Hi!"

通過立即調(diào)用類構(gòu)造函數(shù)可以創(chuàng)建單例:

//使用  new  來配合類表達(dá)式,并在表達(dá)式后面添加括號(hào)
let person = new class {
    constructor(name) {
        this.name = name;
    }
    sayName() {
        console.log(this.name);
    }
}("Nicholas");
person.sayName(); // "Nicholas"
訪問器屬性

自有屬性需要在類構(gòu)造器中創(chuàng)建,而類還允許你在原型上定義訪問器屬性:

class CustomHTMLElement {
    constructor(element) {
        this.element = element;
    }
    get html() {
        return this.element.innerHTML;
    }
    set html(value) {
        this.element.innerHTML = value;
    }
}
var descriptor = Object.getOwnPropertyDescriptor(CustomHTMLElement.prototype, "html");
console.log("get" in descriptor); // true
console.log("set" in descriptor); // true
console.log(descriptor.enumerable); // false

非類的等價(jià)表示如下:

// 直接等價(jià)于上個(gè)范例
let CustomHTMLElement = (function() {
    "use strict";
    const CustomHTMLElement = function(element) {
        // 確認(rèn)函數(shù)被調(diào)用時(shí)使用了 new
        if (typeof new.target === "undefined") {
            throw new Error("Constructor must be called with new.");
        }
        this.element = element;
    }
Object.defineProperty(CustomHTMLElement.prototype, "html", {
    enumerable: false,
    configurable: true,
    get: function() {
        return this.element.innerHTML;
    },
    set: function(value) {
        this.element.innerHTML = value;
    }
});
    return CustomHTMLElement;
}());
需計(jì)算的成員名

無須使用標(biāo)識(shí)符,而是用方括號(hào)來包裹一個(gè)表達(dá)式:

let methodName = "sayName";
class PersonClass {
    constructor(name) {
        this.name = name;
    }
    [methodName]() {
        console.log(this.name);
    }
}
let me = new PersonClass("Nicholas");
me.sayName(); // "Nicholas"

訪問器屬性能以相同方式使用需計(jì)算的名稱,就像這樣:

let propertyName = "html";
class CustomHTMLElement {
    constructor(element) {
        this.element = element;
    }
    get [propertyName]() {
        return this.element.innerHTML;
    }
    set [propertyName](value) {
        this.element.innerHTML = value;
    }
}
生成器方法

你已學(xué)會(huì)如何在對(duì)象字面量上定義一個(gè)生成器:只要在方法名稱前附加一個(gè)星號(hào)( * )。這一語(yǔ)法對(duì)類同樣有效,允許將任何方法變?yōu)橐粋€(gè)生成器:

class MyClass {
    *createIterator() {
        yield 1;
        yield 2;
        yield 3;
    }
}
let instance = new MyClass();
let iterator = instance.createIterator();
靜態(tài)成員

直接在構(gòu)造器上添加額外方法來模擬靜態(tài)成員,這在 ES5 及更早版本中是另一個(gè)通用的模式:

function PersonType(name) {
    this.name = name;
}
// 靜態(tài)方法
PersonType.create = function(name) {
    return new PersonType(name);
};
// 實(shí)例方法
PersonType.prototype.sayName = function() {
    console.log(this.name);
};
var person = PersonType.create("Nicholas");

ES6 的類簡(jiǎn)化了靜態(tài)成員的創(chuàng)建,只要在方法與訪問器屬性的名稱前添加正式的 static 標(biāo)注:

class PersonClass {
    // 等價(jià)于 PersonType 構(gòu)造器
    constructor(name) {
        this.name = name;
    }
    // 等價(jià)于 PersonType.prototype.sayName
    sayName() {
        console.log(this.name);
    }
    // 等價(jià)于 PersonType.create
    static create(name) {
        return new PersonClass(name);
    }
}
let person = PersonClass.create("Nicholas");

和普通方法不一樣的是,static修飾的方法不能在實(shí)例中訪問,只能在類中直接訪問。

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

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

相關(guān)文章

  • 深入理解ES6筆記—— JavaScript中的類class(9)

    摘要:新建一個(gè)類該函數(shù)返回一個(gè)類的實(shí)例給函數(shù)傳入通過立即調(diào)用類構(gòu)造函數(shù)可以創(chuàng)建單例。派生類是指繼承自其它類的新類。在構(gòu)造函數(shù)中訪問之前要調(diào)用,負(fù)責(zé)初始化。在構(gòu)造函數(shù)中使用通常表示當(dāng)前的構(gòu)造函數(shù)名。 ES5中的近類結(jié)構(gòu) ES5以及之前的版本,沒有類的概念,但是聰明的JavaScript開發(fā)者,為了實(shí)現(xiàn)面向?qū)ο?,?chuàng)建了特殊的近類結(jié)構(gòu)。 ES5中創(chuàng)建類的方法:新建一個(gè)構(gòu)造函數(shù),定義一個(gè)方法并且賦值...

    gggggggbong 評(píng)論0 收藏0
  • 深入理解ES6筆記—— JavaScript中的類class(9)

    摘要:新建一個(gè)類該函數(shù)返回一個(gè)類的實(shí)例給函數(shù)傳入通過立即調(diào)用類構(gòu)造函數(shù)可以創(chuàng)建單例。派生類是指繼承自其它類的新類。在構(gòu)造函數(shù)中訪問之前要調(diào)用,負(fù)責(zé)初始化。在構(gòu)造函數(shù)中使用通常表示當(dāng)前的構(gòu)造函數(shù)名。 ES5中的近類結(jié)構(gòu) ES5以及之前的版本,沒有類的概念,但是聰明的JavaScript開發(fā)者,為了實(shí)現(xiàn)面向?qū)ο?,?chuàng)建了特殊的近類結(jié)構(gòu)。 ES5中創(chuàng)建類的方法:新建一個(gè)構(gòu)造函數(shù),定義一個(gè)方法并且賦值...

    Jason 評(píng)論0 收藏0
  • 深入理解ES6筆記——導(dǎo)讀

    摘要:最近買了深入理解的書籍來看,為什么學(xué)習(xí)這么久還要買這本書呢主要是看到核心團(tuán)隊(duì)成員及的創(chuàng)造者為本書做了序,作為一個(gè)粉絲,還是挺看好這本書能給我?guī)硪粋€(gè)新的升華,而且本書的作者也非常厲害。 使用ES6開發(fā)已經(jīng)有1年多了,以前看的是阮一峰老師的ES6教程,也看過MDN文檔的ES6語(yǔ)法介紹。 最近買了《深入理解ES6》的書籍來看,為什么學(xué)習(xí)ES6這么久還要買這本書呢?主要是看到Daniel A...

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

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

0條評(píng)論

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