1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        ES6、ES7、ES8學(xué)習(xí)指南(復(fù)習(xí)下)

        共 15145字,需瀏覽 31分鐘

         ·

        2020-11-18 14:50


        作者:CrazyCodeBoy?

        鏈接:https://www.jianshu.com/p/1ae1dd4cdaa7

        概述

        ES全稱ECMAScript,ECMAScript是ECMA制定的標(biāo)準(zhǔn)化腳本語言。目前JavaScript使用的ECMAScript版本為ECMAScript-262。

        ECMAScript 標(biāo)準(zhǔn)建立在一些原有的技術(shù)上,最為著名的是 JavaScript (網(wǎng)景) 和 JScript (微軟)。它最初由網(wǎng)景的 Brendan Eich 發(fā)明,第一次出現(xiàn)是在網(wǎng)景的 Navigator 2.0 瀏覽器上。Netscape 2.0 以及微軟 Internet Explorer 3.0 后序的所有瀏覽器上都有它的身影。

        了解這些特性,不僅能使我們的編碼更加的符合規(guī)范,而且能提高我們Coding的效率。

        ES6的特性

        ES6的特性比較多,在 ES5 發(fā)布近 6 年(2009-11 至 2015-6)之后才將其標(biāo)準(zhǔn)化。兩個(gè)發(fā)布版本之間時(shí)間跨度很大,所以ES6中的特性比較多。

        在這里列舉幾個(gè)常用的:

        • 模塊化
        • 箭頭函數(shù)
        • 函數(shù)參數(shù)默認(rèn)值
        • 模板字符串
        • 解構(gòu)賦值
        • 延展操作符
        • 對(duì)象屬性簡寫
        • Promise
        • Let與Const

        1.類(class)

        對(duì)熟悉Java,object-c,c#等純面向?qū)ο笳Z言的開發(fā)者來說,都會(huì)對(duì)class有一種特殊的情懷。ES6 引入了class(類),讓JavaScript的面向?qū)ο缶幊套兊酶雍唵魏鸵子诶斫狻?/p>

        ?class?Animal?{
        ????//?構(gòu)造函數(shù),實(shí)例化的時(shí)候?qū)?huì)被調(diào)用,如果不指定,那么會(huì)有一個(gè)不帶參數(shù)的默認(rèn)構(gòu)造函數(shù).
        ????constructor(name,color)?{
        ??????this.name?=?name;
        ??????this.color?=?color;
        ????}
        ????//?toString?是原型對(duì)象上的屬性
        ????toString()?{
        ??????console.log('name:'?+?this.name?+?',color:'?+?this.color);

        ????}
        ??}

        ?var?animal?=?new?Animal('dog','white');//實(shí)例化Animal
        ?animal.toString();

        ?console.log(animal.hasOwnProperty('name'));?//true
        ?console.log(animal.hasOwnProperty('toString'));?//?false
        ?console.log(animal.__proto__.hasOwnProperty('toString'));?//?true

        ?class?Cat?extends?Animal?{
        ??constructor(action)?{
        ????//?子類必須要在constructor中指定super?函數(shù),否則在新建實(shí)例的時(shí)候會(huì)報(bào)錯(cuò).
        ????//?如果沒有置頂consructor,默認(rèn)帶super函數(shù)的constructor將會(huì)被添加、
        ????super('cat','white');
        ????this.action?=?action;
        ??}
        ??toString()?{
        ????console.log(super.toString());
        ??}
        ?}

        ?var?cat?=?new?Cat('catch')
        ?cat.toString();

        ?//?實(shí)例cat 是 Cat 和 Animal 的實(shí)例,和Es5完全一致。
        ?console.log(cat?instanceof?Cat);?//?true
        ?console.log(cat?instanceof?Animal);?//?true?

        2.模塊化(Module)

        ES5不支持原生的模塊化,在ES6中模塊作為重要的組成部分被添加進(jìn)來。模塊的功能主要由 export 和 import 組成。每一個(gè)模塊都有自己單獨(dú)的作用域,模塊之間的相互調(diào)用關(guān)系是通過 export 來規(guī)定模塊對(duì)外暴露的接口,通過import來引用其它模塊提供的接口。同時(shí)還為模塊創(chuàng)造了命名空間,防止函數(shù)的命名沖突。

        導(dǎo)出(export)

        ES6允許在一個(gè)模塊中使用export來導(dǎo)出多個(gè)變量或函數(shù)。

        導(dǎo)出變量

        //test.js
        export?var?name?=?'Rainbow'?

        心得:ES6不僅支持變量的導(dǎo)出,也支持常量的導(dǎo)出。export const sqrt = Math.sqrt;//導(dǎo)出常量

        ES6將一個(gè)文件視為一個(gè)模塊,上面的模塊通過 export 向外輸出了一個(gè)變量。一個(gè)模塊也可以同時(shí)往外面輸出多個(gè)變量。

        ?//test.js
        ?var?name?=?'Rainbow';
        ?var?age?=?'24';
        ?export?{name,?age};?

        導(dǎo)出函數(shù)

        //?myModule.js
        export?function?myModule(someArg)?{
        ??return?someArg;
        }?

        導(dǎo)入(import)

        定義好模塊的輸出以后就可以在另外一個(gè)模塊通過import引用。

        import?{myModule}?from?'myModule';//?main.js
        import?{name,age}?from?'test';//?test.js?

        心得:一條import 語句可以同時(shí)導(dǎo)入默認(rèn)函數(shù)和其它變量。import defaultMethod, { otherMethod } from 'xxx.js';

        3.箭頭(Arrow)函數(shù)

        這是ES6中最令人激動(dòng)的特性之一。=>不只是關(guān)鍵字function的簡寫,它還帶來了其它好處。箭頭函數(shù)與包圍它的代碼共享同一個(gè)this,能幫你很好的解決this的指向問題。有經(jīng)驗(yàn)的JavaScript開發(fā)者都熟悉諸如var self = this;var that = this這種引用外圍this的模式。但借助=>,就不需要這種模式了。

        箭頭函數(shù)的結(jié)構(gòu)

        箭頭函數(shù)的箭頭=>之前是一個(gè)空括號(hào)、單個(gè)的參數(shù)名、或用括號(hào)括起的多個(gè)參數(shù)名,而箭頭之后可以是一個(gè)表達(dá)式(作為函數(shù)的返回值),或者是用花括號(hào)括起的函數(shù)體(需要自行通過return來返回值,否則返回的是undefined)。

        //?箭頭函數(shù)的例子
        ()=>1
        v=>v+1
        (a,b)=>a+b
        ()=>{
        ????alert("foo");
        }
        e=>{
        ????if?(e?==?0){
        ????????return?0;
        ????}
        ????return?1000/e;
        }?

        心得:不論是箭頭函數(shù)還是bind,每次被執(zhí)行都返回的是一個(gè)新的函數(shù)引用,因此如果你還需要函數(shù)的引用去做一些別的事情(譬如卸載監(jiān)聽器),那么你必須自己保存這個(gè)引用。

        卸載監(jiān)聽器時(shí)的陷阱

        錯(cuò)誤的做法

        class?PauseMenu?extends?React.Component{
        ????componentWillMount(){
        ????????AppStateIOS.addEventListener('change',?this.onAppPaused.bind(this));
        ????}
        ????componentWillUnmount(){
        ????????AppStateIOS.removeEventListener('change',?this.onAppPaused.bind(this));
        ????}
        ????onAppPaused(event){
        ????}
        }?

        正確的做法

        class?PauseMenu?extends?React.Component{
        ????constructor(props){
        ????????super(props);
        ????????this._onAppPaused?=?this.onAppPaused.bind(this);
        ????}
        ????componentWillMount(){
        ????????AppStateIOS.addEventListener('change',?this._onAppPaused);
        ????}
        ????componentWillUnmount(){
        ????????AppStateIOS.removeEventListener('change',?this._onAppPaused);
        ????}
        ????onAppPaused(event){
        ????}
        }?

        除上述的做法外,我們還可以這樣做:

        class?PauseMenu?extends?React.Component{
        ????componentWillMount(){
        ????????AppStateIOS.addEventListener('change',?this.onAppPaused);
        ????}
        ????componentWillUnmount(){
        ????????AppStateIOS.removeEventListener('change',?this.onAppPaused);
        ????}
        ????onAppPaused?=?(event)?=>?{
        ????????//把函數(shù)直接作為一個(gè)arrow?function的屬性來定義,初始化的時(shí)候就綁定好了this指針
        ????}
        }?

        需要注意的是:不論是bind還是箭頭函數(shù),每次被執(zhí)行都返回的是一個(gè)新的函數(shù)引用,因此如果你還需要函數(shù)的引用去做一些別的事情(譬如卸載監(jiān)聽器),那么你必須自己保存這個(gè)引用。

        4.函數(shù)參數(shù)默認(rèn)值

        ES6支持在定義函數(shù)的時(shí)候?yàn)槠湓O(shè)置默認(rèn)值:

        function?foo(height?=?50,?color?=?'red')
        {
        ????//?...
        }?

        不使用默認(rèn)值:

        function?foo(height,?color)
        {
        ????var?height?=?height?||?50;
        ????var?color?=?color?||?'red';
        ????//...
        }?

        這樣寫一般沒問題,但當(dāng)參數(shù)的布爾值為false時(shí),就會(huì)有問題了。比如,我們這樣調(diào)用foo函數(shù):

        foo(0,?"")?

        因?yàn)?code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: 'Operator Mono', Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(0, 150, 136);">0的布爾值為false,這樣height的取值將是50。同理color的取值為‘red’。

        所以說,函數(shù)參數(shù)默認(rèn)值不僅能是代碼變得更加簡潔而且能規(guī)避一些問題。

        5.模板字符串

        ES6支持模板字符串,使得字符串的拼接更加的簡潔、直觀。

        不使用模板字符串:

        var?name?=?'Your?name?is?'?+?first?+?'?'?+?last?+?'.'?

        使用模板字符串:

        var?name?=?`Your?name?is?${first}?${last}.`?

        在ES6中通過${}就可以完成字符串的拼接,只需要將變量放在大括號(hào)之中。

        6.解構(gòu)賦值

        解構(gòu)賦值語法是JavaScript的一種表達(dá)式,可以方便的從數(shù)組或者對(duì)象中快速提取值賦給定義的變量。

        獲取數(shù)組中的值

        從數(shù)組中獲取值并賦值到變量中,變量的順序與數(shù)組中對(duì)象順序?qū)?yīng)。

        var?foo?=?["one",?"two",?"three",?"four"];

        var?[one,?two,?three]?=?foo;
        console.log(one);?//?"one"
        console.log(two);?//?"two"
        console.log(three);?//?"three"

        //如果你要忽略某些值,你可以按照下面的寫法獲取你想要的值
        var?[first,?,?,?last]?=?foo;
        console.log(first);?//?"one"
        console.log(last);?//?"four"

        //你也可以這樣寫
        var?a,?b;?//先聲明變量

        [a,?b]?=?[1,?2];
        console.log(a);?//?1
        console.log(b);?//?2?

        如果沒有從數(shù)組中的獲取到值,你可以為變量設(shè)置一個(gè)默認(rèn)值。

        var?a,?b;

        [a=5,?b=7]?=?[1];
        console.log(a);?//?1
        console.log(b);?//?7?

        通過解構(gòu)賦值可以方便的交換兩個(gè)變量的值。

        var?a?=?1;
        var?b?=?3;

        [a,?b]?=?[b,?a];
        console.log(a);?//?3
        console.log(b);?//?1?

        獲取對(duì)象中的值

        const?student?=?{
        ??name:'Ming',
        ??age:'18',
        ??city:'Shanghai'??
        };

        const?{name,age,city}?=?student;
        console.log(name);?//?"Ming"
        console.log(age);?//?"18"
        console.log(city);?//?"Shanghai"?

        7.延展操作符(Spread operator)

        延展操作符...可以在函數(shù)調(diào)用/數(shù)組構(gòu)造時(shí), 將數(shù)組表達(dá)式或者string在語法層面展開;還可以在構(gòu)造對(duì)象時(shí), 將對(duì)象表達(dá)式按key-value的方式展開。

        語法

        函數(shù)調(diào)用:

        myFunction(...iterableObj);?

        數(shù)組構(gòu)造或字符串:

        [...iterableObj,?'4',?...'hello',?6];?

        構(gòu)造對(duì)象時(shí),進(jìn)行克隆或者屬性拷貝(ECMAScript 2018規(guī)范新增特性):

        let?objClone?=?{?...obj?};?

        應(yīng)用場景

        在函數(shù)調(diào)用時(shí)使用延展操作符

        function?sum(x,?y,?z)?{
        ??return?x?+?y?+?z;
        }
        const?numbers?=?[1,?2,?3];

        //不使用延展操作符
        console.log(sum.apply(null,?numbers));

        //使用延展操作符
        console.log(sum(...numbers));//?6?

        構(gòu)造數(shù)組

        沒有展開語法的時(shí)候,只能組合使用 push,splice,concat 等方法,來將已有數(shù)組元素變成新數(shù)組的一部分。有了展開語法, 構(gòu)造新數(shù)組會(huì)變得更簡單、更優(yōu)雅:

        const?stuendts?=?['Jine','Tom'];?
        const?persons?=?['Tony',...?stuendts,'Aaron','Anna'];
        conslog.log(persions)//?["Tony",?"Jine",?"Tom",?"Aaron",?"Anna"]?

        和參數(shù)列表的展開類似, ... 在構(gòu)造字?jǐn)?shù)組時(shí), 可以在任意位置多次使用。

        數(shù)組拷貝

        var?arr?=?[1,?2,?3];
        var?arr2?=?[...arr];?//?等同于?arr.slice()
        arr2.push(4);?
        console.log(arr2)//[1,?2,?3,?4]?

        展開語法和 Object.assign() 行為一致, 執(zhí)行的都是淺拷貝(只遍歷一層)。

        連接多個(gè)數(shù)組

        var?arr1?=?[0,?1,?2];
        var?arr2?=?[3,?4,?5];
        var?arr3?=?[...arr1,?...arr2];//?將?arr2?中所有元素附加到?arr1?后面并返回
        //等同于
        var?arr4?=?arr1.concat(arr2);?

        在ECMAScript 2018中延展操作符增加了對(duì)對(duì)象的支持

        var?obj1?=?{?foo:?'bar',?x:?42?};
        var?obj2?=?{?foo:?'baz',?y:?13?};

        var?clonedObj?=?{?...obj1?};
        //?克隆后的對(duì)象:?{?foo:?"bar",?x:?42?}

        var?mergedObj?=?{?...obj1,?...obj2?};
        //?合并后的對(duì)象:?{?foo:?"baz",?x:?42,?y:?13?}?

        在React中的應(yīng)用

        通常我們在封裝一個(gè)組件時(shí),會(huì)對(duì)外公開一些 props 用于實(shí)現(xiàn)功能。大部分情況下在外部使用都應(yīng)顯示的傳遞 props 。但是當(dāng)傳遞大量的props時(shí),會(huì)非常繁瑣,這時(shí)我們可以使用 ...(延展操作符,用于取出參數(shù)對(duì)象的所有可遍歷屬性) 來進(jìn)行傳遞。

        一般情況下我們應(yīng)該這樣寫

        <CustomComponent?name?='Jine'?age?={21}?/>?

        使用 ... ,等同于上面的寫法

        const?params?=?{
        ????????name:?'Jine',
        ????????age:?21
        ????}

        params}?/>?

        配合解構(gòu)賦值避免傳入一些不需要的參數(shù)

        var params = {
        name: '123',
        title: '456',
        type: 'aaa'
        }

        var { type, ...other } = params;


        //等同于

        8.對(duì)象屬性簡寫

        在ES6中允許我們在設(shè)置一個(gè)對(duì)象的屬性的時(shí)候不指定屬性名。

        不使用ES6

        const?name='Ming',age='18',city='Shanghai';
        ????????
        const?student?=?{
        ????name:name,
        ????age:age,
        ????city:city
        };
        console.log(student);//{name:?"Ming",?age:?"18",?city:?"Shanghai"}?

        對(duì)象中必須包含屬性和值,顯得非常冗余。

        使用ES6

        const?name='Ming',age='18',city='Shanghai';
        ????????
        const?student?=?{
        ????name,
        ????age,
        ????city
        };
        console.log(student);//{name:?"Ming",?age:?"18",?city:?"Shanghai"}?

        對(duì)象中直接寫變量,非常簡潔。

        9.Promise

        Promise 是異步編程的一種解決方案,比傳統(tǒng)的解決方案callback更加的優(yōu)雅。它最早由社區(qū)提出和實(shí)現(xiàn)的,ES6 將其寫進(jìn)了語言標(biāo)準(zhǔn),統(tǒng)一了用法,原生提供了Promise對(duì)象。

        不使用ES6

        嵌套兩個(gè)setTimeout回調(diào)函數(shù):

        setTimeout(function()
        {
        ????console.log('Hello');?//?1秒后輸出"Hello"
        ????setTimeout(function()
        ????
        {
        ????????console.log('Hi');?//?2秒后輸出"Hi"
        ????},?1000);
        },?1000);?

        使用ES6

        var?waitSecond?=?new?Promise(function(resolve,?reject)
        {
        ????setTimeout(resolve,?1000);
        });

        waitSecond
        ????.then(function()
        ????
        {
        ????????console.log("Hello");?//?1秒后輸出"Hello"
        ????????return?waitSecond;
        ????})
        ????.then(function()
        ????
        {
        ????????console.log("Hi");?//?2秒后輸出"Hi"
        ????});?

        上面的的代碼使用兩個(gè)then來進(jìn)行異步編程串行化,避免了回調(diào)地獄:

        10.支持let與const

        在之前JS是沒有塊級(jí)作用域的,const與let填補(bǔ)了這方便的空白,const與let都是塊級(jí)作用域。

        使用var定義的變量為函數(shù)級(jí)作用域:

        {
        ??var?a?=?10;
        }

        console.log(a);?//?輸出10?

        使用let與const定義的變量為塊級(jí)作用域:

        {
        ??let?a?=?10;
        }

        console.log(a);?//-1?or?Error“ReferenceError:?a?is?not?defined”?

        ES7的特性

        在ES6之后,ES的發(fā)布頻率更加頻繁,基本每年一次,所以自ES6之后,每個(gè)新版本的特性的數(shù)量就比較少。

        • includes()
        • 指數(shù)操作符

        1. Array.prototype.includes()

        includes() 函數(shù)用來判斷一個(gè)數(shù)組是否包含一個(gè)指定的值,如果包含則返回 true,否則返回false。

        includes 函數(shù)與 indexOf 函數(shù)很相似,下面兩個(gè)表達(dá)式是等價(jià)的:

        arr.includes(x)
        arr.indexOf(x) >= 0

        接下來我們來判斷數(shù)字中是否包含某個(gè)元素:

        在ES7之前的做法

        使用indexOf()驗(yàn)證數(shù)組中是否存在某個(gè)元素,這時(shí)需要根據(jù)返回值是否為-1來判斷:

        let?arr?=?['react',?'angular',?'vue'];

        if?(arr.indexOf('react')?!==?-1)
        {
        ????console.log('react存在');
        }?

        使用ES7的includes()

        使用includes()驗(yàn)證數(shù)組中是否存在某個(gè)元素,這樣更加直觀簡單:

        let?arr?=?['react',?'angular',?'vue'];

        if?(arr.includes('react'))
        {
        ????console.log('react存在');
        }?

        2.指數(shù)操作符

        在ES7中引入了指數(shù)運(yùn)算符**,**具有與Math.pow(..)等效的計(jì)算結(jié)果。

        不使用指數(shù)操作符

        使用自定義的遞歸函數(shù)calculateExponent或者M(jìn)ath.pow()進(jìn)行指數(shù)運(yùn)算:

        function?calculateExponent(base,?exponent)
        {
        ????if?(exponent?===?1)
        ????{
        ????????return?base;
        ????}
        ????else
        ????{
        ????????return?base?*?calculateExponent(base,?exponent?-?1);
        ????}
        }

        console.log(calculateExponent(2,?10));?//?輸出1024
        console.log(Math.pow(2,?10));?//?輸出1024?

        使用指數(shù)操作符

        使用指數(shù)運(yùn)算符**,就像+、-等操作符一樣:

        console.log(2**10);//?輸出1024?

        ES8的特性

        • async/await
        • Object.values()
        • Object.entries()
        • String padding
        • 函數(shù)參數(shù)列表結(jié)尾允許逗號(hào)
        • Object.getOwnPropertyDescriptors()

        瀏覽器兼容性

        1.async/await

        在ES8中加入了對(duì)async/await的支持,也就我們所說的異步函數(shù),這是一個(gè)很實(shí)用的功能。async/await將我們從頭痛的回調(diào)地獄中解脫出來了,使整個(gè)代碼看起來很簡潔。

        使用async/await與不使用async/await的差別:

        login(userName)?{
        ????return?new?Promise((resolve,?reject)?=>?{
        ????????setTimeout(()?=>?{
        ????????????resolve('1001');
        ????????},?600);
        ????});
        }

        getData(userId)?{
        ????return?new?Promise((resolve,?reject)?=>?{
        ????????setTimeout(()?=>?{
        ????????????if?(userId?===?'1001')?{
        ????????????????resolve('Success');
        ????????????}?else?{
        ????????????????reject('Fail');
        ????????????}
        ????????},?600);
        ????});
        }

        //?不使用async/await?ES7
        doLogin(userName)?{
        ????this.login(userName)
        ????????.then(this.getData)
        ????????.then(result?=>?{
        ????????????console.log(result)
        ????????})
        }

        //?使用async/await?ES8
        async?doLogin2(userName)?{
        ????const?userId=await?this.login(userName);
        ????const?result=await?this.getData(userId);
        }

        this.doLogin()//?Success
        this.doLogin2()//?Success?

        async/await的幾種應(yīng)用場景

        接下來我們來看一下async/await的幾種應(yīng)用場景。

        獲取異步函數(shù)的返回值

        異步函數(shù)本身會(huì)返回一個(gè)Promise,所以我們可以通過then來獲取異步函數(shù)的返回值。

        async?function?charCountAdd(data1,?data2)?{
        ????const?d1=await?charCount(data1);
        ????const?d2=await?charCount(data2);
        ????return?d1+d2;
        }
        charCountAdd('Hello','Hi').then(console.log);//通過then獲取異步函數(shù)的返回值。
        function?charCount(data)?{
        ????return?new?Promise((resolve,?reject)?=>?{
        ????????setTimeout(()?=>?{
        ????????????resolve(data.length);
        ????????},?1000);
        ????});
        }?

        async/await在并發(fā)場景中的應(yīng)用

        對(duì)于上述的例子,我們調(diào)用await兩次,每次都是等待1秒一共是2秒,效率比較低,而且兩次await的調(diào)用并沒有依賴關(guān)系,那能不能讓其并發(fā)執(zhí)行呢,答案是可以的,接下來我們通過Promise.all來實(shí)現(xiàn)await的并發(fā)調(diào)用。

        async?function?charCountAdd(data1,?data2)?{
        ????const?[d1,d2]=await?Promise.all([charCount(data1),charCount(data2)]);
        ????return?d1+d2;
        }
        charCountAdd('Hello','Hi').then(console.log);
        function?charCount(data)?{
        ????return?new?Promise((resolve,?reject)?=>?{
        ????????setTimeout(()?=>?{
        ????????????resolve(data.length);
        ????????},?1000);
        ????});
        }?

        通過上述代碼我們實(shí)現(xiàn)了兩次charCount的并發(fā)調(diào)用,Promise.all接受的是一個(gè)數(shù)組,它可以將數(shù)組中的promise對(duì)象并發(fā)執(zhí)行;

        async/await的幾種錯(cuò)誤處理方式

        第一種:捕捉整個(gè)async/await函數(shù)的錯(cuò)誤

        async?function?charCountAdd(data1,?data2)?{
        ????const?d1=await?charCount(data1);
        ????const?d2=await?charCount(data2);
        ????return?d1+d2;
        }
        charCountAdd('Hello','Hi')
        ????.then(console.log)
        ????.catch(console.log);//捕捉整個(gè)async/await函數(shù)的錯(cuò)誤
        ...?

        這種方式可以捕捉整個(gè)charCountAdd運(yùn)行過程中出現(xiàn)的錯(cuò)誤,錯(cuò)誤可能是由charCountAdd本身產(chǎn)生的,也可能是由對(duì)data1的計(jì)算中或data2的計(jì)算中產(chǎn)生的。

        第二種:捕捉單個(gè)的await表達(dá)式的錯(cuò)誤

        async?function?charCountAdd(data1,?data2)?{
        ????const?d1=await?charCount(data1)
        ????????.catch(e=>console.log('d1?is?null'));
        ????const?d2=await?charCount(data2)
        ????????.catch(e=>console.log('d2?is?null'));
        ????return?d1+d2;
        }
        charCountAdd('Hello','Hi').then(console.log);?

        通過這種方式可以捕捉每一個(gè)await表達(dá)式的錯(cuò)誤,如果既要捕捉每一個(gè)await表達(dá)式的錯(cuò)誤,又要捕捉整個(gè)charCountAdd函數(shù)的錯(cuò)誤,可以在調(diào)用charCountAdd的時(shí)候加個(gè)catch。

        ...
        charCountAdd('Hello','Hi')
        ????.then(console.log)
        ????.catch(console.log);//捕捉整個(gè)async/await函數(shù)的錯(cuò)誤
        ...?

        第三種:同時(shí)捕捉多個(gè)的await表達(dá)式的錯(cuò)誤

        async?function?charCountAdd(data1,?data2)?{
        ????let?d1,d2;
        ????try?{
        ????????d1=await?charCount(data1);
        ????????d2=await?charCount(data2);
        ????}catch?(e){
        ????????console.log('d1?is?null');
        ????}
        ????return?d1+d2;
        }
        charCountAdd('Hello','Hi')
        ????.then(console.log);

        function?charCount(data)?{
        ????return?new?Promise((resolve,?reject)?=>?{
        ????????setTimeout(()?=>?{
        ????????????resolve(data.length);
        ????????},?1000);
        ????});
        }?

        2.Object.values()

        Object.values()是一個(gè)與Object.keys()類似的新函數(shù),但返回的是Object自身屬性的所有值,不包括繼承的值。

        假設(shè)我們要遍歷如下對(duì)象obj的所有值:

        const?obj?=?{a:?1,?b:?2,?c:?3};?

        不使用Object.values() :ES7

        const?vals=Object.keys(obj).map(key=>obj[key]);
        console.log(vals);//[1,?2,?3]?

        使用Object.values() :ES8

        const?values=Object.values(obj1);
        console.log(values);//[1,?2,?3]?

        從上述代碼中可以看出Object.values()為我們省去了遍歷key,并根據(jù)這些key獲取value的步驟。

        3.Object.entries

        Object.entries()函數(shù)返回一個(gè)給定對(duì)象自身可枚舉屬性的鍵值對(duì)的數(shù)組。

        接下來我們來遍歷上文中的obj對(duì)象的所有屬性的key和value:

        不使用Object.entries() :ES7

        Object.keys(obj).forEach(key=>{
        ????console.log('key:'+key+'?value:'+obj[key]);
        })
        //key:a?value:1
        //key:b?value:2
        //key:c?value:3?

        使用Object.entries() :ES8

        for(let?[key,value]?of?Object.entries(obj1)){
        ????console.log(`key:?${key}?value:${value}`)
        }
        //key:a?value:1
        //key:b?value:2
        //key:c?value:3?

        4.String padding

        在ES8中String新增了兩個(gè)實(shí)例函數(shù)String.prototype.padStartString.prototype.padEnd,允許將空字符串或其他字符串添加到原始字符串的開頭或結(jié)尾。

        String.padStart(targetLength,[padString])

        • targetLength:當(dāng)前字符串需要填充到的目標(biāo)長度。如果這個(gè)數(shù)值小于當(dāng)前字符串的長度,則返回當(dāng)前字符串本身。
        • padString:(可選)填充字符串。如果字符串太長,使填充后的字符串長度超過了目標(biāo)長度,則只保留最左側(cè)的部分,其他部分會(huì)被截?cái)?,此參?shù)的缺省值為 " "。
        console.log('0.0'.padStart(4,'10'))?//10.0
        console.log('0.0'.padStart(20))//????????????????0.00?

        String.padEnd(targetLength,padString])

        • targetLength:當(dāng)前字符串需要填充到的目標(biāo)長度。如果這個(gè)數(shù)值小于當(dāng)前字符串的長度,則返回當(dāng)前字符串本身。
        • padString:(可選) 填充字符串。如果字符串太長,使填充后的字符串長度超過了目標(biāo)長度,則只保留最左側(cè)的部分,其他部分會(huì)被截?cái)?,此參?shù)的缺省值為 " ";
        console.log('0.0'.padEnd(4,'0'))?//0.00?
        console.log('0.0'.padEnd(10,'0'))//0.00000000?

        4.函數(shù)參數(shù)列表結(jié)尾允許逗號(hào)

        這是一個(gè)不痛不癢的更新,主要作用是方便使用git進(jìn)行多人協(xié)作開發(fā)時(shí)修改同一個(gè)函數(shù)減少不必要的行變更。

        不使用ES8

        //程序員A
        var?f?=?function(a,
        ??b
        ???
        )?
        {?
        ??...
        ??}

        //程序員B
        var?f?=?function(a,
        ??b,???//變更行
        ??c???//變更行
        ???
        )?
        {?
        ??...
        ??}

        //程序員C
        var?f?=?function(a,
        ??b,
        ??c,???//變更行
        ??d???//變更行
        ???
        )?
        {?
        ??...
        ??}?

        使用ES8

        //程序員A
        var?f?=?function(a,
        ??b,
        ???
        )?
        {?
        ??...
        ??}

        //程序員B
        var?f?=?function(a,
        ??b,
        ??c,???//變更行
        ???
        )?
        {?
        ??...
        ??}

        //程序員C
        var?f?=?function(a,
        ??b,
        ??c,
        ??d,???//變更行
        ???
        )?
        {?
        ??...
        ??}?

        5.Object.getOwnPropertyDescriptors()

        Object.getOwnPropertyDescriptors()函數(shù)用來獲取一個(gè)對(duì)象的所有自身屬性的描述符,如果沒有任何自身屬性,則返回空對(duì)象。

        函數(shù)原型:

        Object.getOwnPropertyDescriptors(obj)?

        返回obj對(duì)象的所有自身屬性的描述符,如果沒有任何自身屬性,則返回空對(duì)象。

        const?obj2?=?{
        ????name:?'Jine',
        ????get?age()?{?return?'18'?}
        };
        Object.getOwnPropertyDescriptors(obj2)
        //?{
        //???age:?{
        //?????configurable:?true,
        //?????enumerable:?true,
        //?????get:?function?age(){},?//the?getter?function
        //?????set:?undefined
        //???},
        //???name:?{
        //?????configurable:?true,
        //?????enumerable:?true,
        //??????value:"Jine",
        //??????writable:true
        //???}
        //?}?

        總結(jié)

        技術(shù)更替的車輪一直在前進(jìn)中,JavaScript的規(guī)范和標(biāo)準(zhǔn)也在不斷的制定和完善。你會(huì)發(fā)現(xiàn)ECMAScript 新版的很多特性已經(jīng)是Typescript,瀏覽器或其他polyfills的一部分,就拿ES8的async/await來說,它是2017年6月被納入ECMAScript的,但我在2016年的時(shí)候就已經(jīng)開始使用這個(gè)特性了,這些特性通常由ECMAScript議員提交,然后會(huì)出現(xiàn)在在未來的某個(gè)ECMAScript版本中。

        參考

        • MDN
        • ECMAScript? 2016
        • ECMAScript? 2016 語言標(biāo)準(zhǔn)
        • ECMAScript? 2017

        ??愛心三連擊

        1.看到這里了就點(diǎn)個(gè)在看支持下吧,你的點(diǎn)贊,在看是我創(chuàng)作的動(dòng)力。

        2.關(guān)注公眾號(hào)程序員成長指北,回復(fù)「1」加入Node進(jìn)階交流群!「在這里有好多 Node 開發(fā)者,會(huì)討論 Node 知識(shí),互相學(xué)習(xí)」!

        3.也可添加微信【ikoala520】,一起成長。


        “在看轉(zhuǎn)發(fā)”是最大的支持

        瀏覽 47
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            一级黄色片网站 | 国产午夜精品福利 | 女生喷液视频 | 太涨了好深到宫口h | 成人三级在线 | 亚洲激情视频在线 | 揉我胸啊嗯出水了嗯 | 男人成人网站 | 无码视频一区在线观看 | 亚州无码 |