1. ES6特性總結

        共 10557字,需瀏覽 22分鐘

         ·

        2021-02-11 08:40

        點擊上方藍色字體,選擇“置頂或者星標”?


        優(yōu)質文章第一時間送達!


        ES6特性總結

        簡介

        ECMAScript6.0(以下簡稱ES6,ECMAScript是一種由Ecma國際(前身為歐洲計算機制造商協(xié)會,英文名稱是EuropeanComputerManufacturersAssociation)通過ECMA-262標準化的腳本程序設計語言)是JavaScript語言的下一代標準,已經(jīng)在2015年6月正式發(fā)布了,并且從ECMAScript6開始,開始采用年號來做版本。即ECMAScript2015,就是ECMAScript6。它的目標,是使得JavaScript語言可以用來編寫復雜的大型應用程序,成為企業(yè)級開發(fā)語言。每年一個新版本。

        什么是ECMAScript

        來看下前端的發(fā)展歷程:

        web1.0時代:

        最初的網(wǎng)頁以HTML為主,是純靜態(tài)的網(wǎng)頁。網(wǎng)頁是只讀的,信息流只能從服務的到客戶端單向流通。開發(fā)人員也只關心頁面的樣式和內(nèi)容即可。

        web2.0時代:

        • 1995年,網(wǎng)景工程師BrendanEich花了10天時間設計了JavaScript語言。
        • 1996年,微軟發(fā)布了JScript,其實是JavaScript的逆向工程實現(xiàn)。
        • 1996年11月,JavaScript的創(chuàng)造者Netscape公司,決定將JavaScript提交給標準化組織ECMA,希望這種語言能夠成為國際標準。
        • 1997年,ECMA發(fā)布262號標準文件(ECMA-262)的第一版,規(guī)定了瀏覽器腳本語言的標準,并將這種語言稱為ECMAScript,這個版本就是1.0版。JavaScript和JScript都是ECMAScript的標準實現(xiàn)者,隨后各大瀏覽器廠商紛紛實現(xiàn)了ECMAScript標準。

        所以,ECMAScript是瀏覽器腳本語言的規(guī)范,而各種我們熟知的js語言,如JavaScript則是規(guī)范的具體實現(xiàn)

        ES6新特性

        1. let聲明變量

        ??//var聲明的變量往往會越域
        ??//let聲明的變量有嚴格局部作用域
        ??{
        ????var?a?=?1;
        ????let?b?=?2;
        ??}
        ??console.log(a);?//1
        ??console.log(b);?//ReferenceError:bisnotdefined
        ??
        ??
        ??//var可以聲明多次
        ??//let只能聲明一次
        ??var?m?=?1
        ??var?m?=?2
        ??let?n?=?3
        ??//let?n?=?4
        ??console.log(m)?//2
        ??console.log(n)?//Identifier'n'hasalreadybeendeclared
        ??
        ??//var會變量提升
        ??//let不存在變量提升
        ??console.log(x);?//undefined
        ??var?x?=?10;
        ??console.log(y);?//ReferenceError:yisnotdefined
        ??let?y?=?20;

        2. const聲明常量(只讀變量)

        ??//1.聲明之后不允許改變
        ??//2.一但聲明必須初始化,否則會報錯
        ??const?a?=?1;
        ??a?=?3;??//UncaughtTypeError:Assignmenttoconstantvariable.

        3. 解構表達式

        數(shù)組結構

        let?arr?=?[1,?2,?3];
        //以前我們想獲取其中的值,只能通過角標。ES6可以這樣:
        const?[x,?y,?z]?=?arr;?//x,y,z將與arr中的每個位置對應來取值//然后打印
        console.log(x,?y,?z);

        對象結構

        const?person?=?{
        ??name:?"jack",
        ??age:?21,
        ??language:?['java', 'js', 'css']
        }

        //解構表達式獲取值,將person里面每一個屬性和左邊對應賦值
        const?{name,?age,?language}?=?person;
        //等價于下面
        //const?name?=?person.name;
        //const?age?=?person.age;
        //const?language?=?person.language;
        //可以分別打印
        console.log(name);
        console.log(age);
        console.log(language);

        //擴展:如果想要將name的值賦值給其他變量,可以如下,nn是新的變量名
        const?{name:?nn,?age,?language}?=?person;
        console.log(nn);
        console.log(age);
        console.log(language);

        4. 字符串擴展

        幾個新的API

        ES6為字符串擴展了幾個新的API:

        • includes():返回布爾值,表示是否找到了參數(shù)字符串。
        • startsWith():返回布爾值,表示參數(shù)字符串是否在原字符串的頭部。
        • endsWith():返回布爾值,表示參數(shù)字符串是否在原字符串的尾部。
        let?str?=?"hello.vue";
        console.log(str.startsWith("hello"));?//true
        console.log(str.endsWith(".vue"));?//true
        console.log(str.includes("e"));?//true
        console.log(str.includes("hello"));?//true

        字符串模板

        模板字符串相當于加強版的字符串,用反引號`,除了作為普通字符串,還可以用來定義多行字符串,還可以在字符串中加入變量和表達式。

        //1、多行字符串
        let?ss?=?`
        ??

        ???helloworld
        ??

        `


        console.log(ss)

        //2、字符串插入變量和表達式。變量名寫在${}中,${}中可以放入JavaScript表達式。


        let?name?="張三";
        let?age?=?18;
        let?info?=?`我是${name},今年${age}了`;
        console.log(info)

        //3、字符串中調(diào)用函數(shù)
        function?fun()?{
        ??return"這是一個函數(shù)"
        }

        let?sss?=?`O(∩_∩)O哈哈~,${fun()}`;
        console.log(sss);?//O(∩_∩)O哈哈~,這是一個函數(shù)

        5. 函數(shù)優(yōu)化

        函數(shù)參數(shù)默認值

        //在ES6以前,我們無法給一個函數(shù)參數(shù)設置默認值,只能采用變通寫法:
        function?add(a,?b)?{
        ??//判斷b是否為空,為空就給默認值1
        ??b?=?b?||?1;
        ??return?a?+?b;
        }

        //傳一個參數(shù)
        console.log(add(10));

        //現(xiàn)在可以這么寫:直接給參數(shù)寫上默認值,沒傳就會自動使用默認值
        function?add2(a,?b?=?1)?{
        ??return?a?+?b;
        }
        //傳一個參數(shù)
        console.log(add2(10));

        不定參數(shù)

        不定參數(shù)用來表示不確定參數(shù)個數(shù),形如,...變量名,由...加上一個具名參數(shù)標識符組成。具名參數(shù)只能放在參數(shù)列表的最后,并且有且只有一個不定參數(shù)

        function?fun(...values){
        ????console.log(values.length)
        }
        fun(1,?2)?//2
        fun(1,?2,?3,?4)?//4

        箭頭函數(shù)

        ES6中定義函數(shù)的簡寫方式

        • 一個參數(shù)時:
        //以前聲明一個方法
        var?print?=?function(obj) {
        ????console.log(obj);
        }


        //可以簡寫為:
        var?print?=?obj?=>?console.log(obj);
        //測試調(diào)用
        print(100);
        • 多個參數(shù):
        //兩個參數(shù)的情況:
        var?sum?=?function(a,?b)?{
        ????return?a + b;
        }
        //簡寫為:
        //當只有一行語句,并且需要返回結果時,可以省略{},結果會自動返回。
        var?sum2?=?(a,?b)?=>?a?+?b;
        //測試調(diào)用
        console.log(sum2(10,?10));?//20

        //代碼不止一行,可以用`{}`括起來
        var?sum3?=?(a,?b)?=>?{
        ??c?=?a?+?b;
        ??return?c;
        };
        //測試調(diào)用
        console.log(sum3(10,?20));?//30

        實戰(zhàn):箭頭函數(shù)結合解構表達式

        //需求,聲明一個對象,hello方法需要對象的個別屬性
        //以前的方式:
        const?person?=?{
        ??name:?"jack",
        ??age:?21,
        ??language:?['java',?'js',?'css']
        }

        function?hello(person)?{
        ?console.log("hello,?"?+?person.name)
        }
        //現(xiàn)在的方式
        var?hello2?=?({name})?=>?{console.log("hello,"?+?name)};
        //測試
        hello2(person);

        6. 對象優(yōu)化

        新增的API

        ES6給Object拓展了許多新的方法,如:

        • keys(obj):獲取對象的所有key形成的數(shù)組
        • values(obj):獲取對象的所有value形成的數(shù)組
        • entries(obj):獲取對象的所有key和value形成的二維數(shù)組。格式:[[k1, v1],[k2, v2],...]
        • assign(dest,...src):將多個src對象的值拷貝到dest中。(第一層為深拷貝,第二層為淺拷貝)
        const?person?=?{
        ??name:?"jack",
        ??age:?21,
        ??language:?['java',?'js',?'css']
        }

        console.log(Object.keys(person));?//["name","age","language"]
        console.log(Object.values(person));?//["jack",21,Array(3)]
        console.log(Object.entries(person));?//[Array(2),Array(2),Array(2)]

        聲明對象簡寫

        const?age?=?23
        const?name?=?"張三"
        //傳統(tǒng)
        const?person1?=?{age:?age,?name:?name}
        console.log(person1)

        //ES6:屬性名和屬性值變量名一樣,可以省略
        const?person2?=?{age,?name}
        console.log(person2)??//{age:23,name:"張三"}

        對象的函數(shù)屬性簡寫

        let?person?=?{
        ??name:?"jack",
        ??//以前:
        ??eat:?function(food)?{
        ????console.log(this.name + "在吃" + food);
        ??},
        ??//箭頭函數(shù)版:這里拿不到this
        ??eat2:?food?=>?console.log(person.name?+?"在吃"?+?food);
        ??//簡寫版:
        ??eat3(food)?{
        ??????console.log(this.name?+?"在吃"?+?food);
        ??}
        }
        person.eat("apple");

        對象拓展運算符

        拓展運算符(...)用于取出參數(shù)對象所有可遍歷屬性然后拷貝到當前對象。

        //1、拷貝對象(深拷貝)
        let?person1?=?{name:?"Amy",?age:?15}
        let?someone?=?{...person1}
        console.log(someone)//{name:?"Amy",?age:?15}
        //2、合并對象
        let?age?=?{age:?15}
        let?name?=?{name:?"Amy"}
        let?person2?=?{...age,?...name}?//如果兩個對象的字段名重復,后面對象字段值會覆蓋前面對象的字段值
        console.log(person2)?//{age:?15,?name:?"Amy"}

        7. map和reduce

        數(shù)組中新增了map和reduce方法。

        map

        map():接收一個函數(shù),將原數(shù)組中的所有元素用這個函數(shù)處理后放入新數(shù)組返回。

        let?arr?=?['1',?'20',?'-5',?'3'];
        console.log(arr)

        arr?=?arr.map(s?=>?parseInt(s));
        console.log(arr)

        reduce

        語法:
        arr.reduce(callback,[initialValue])
        reduce為數(shù)組中的每一個元素依次執(zhí)行回調(diào)函數(shù),不包括數(shù)組中被刪除或從未被賦值的元素,接受四個參數(shù):初始值(或者上一次回調(diào)函數(shù)的返回值),當前元素值,當前索引,調(diào)用reduce的數(shù)組。

        callback(執(zhí)行數(shù)組中每個值的函數(shù),包含四個參數(shù))

        • previousValue(上一次調(diào)用回調(diào)返回的值,或者是提供的初始值(initialValue))
        • currentValue(數(shù)組中當前被處理的元素)
        • index(當前元素在數(shù)組中的索引)
        • array(調(diào)用reduce的數(shù)組)

        initialValue(作為第一次調(diào)用callback的第一個參數(shù)。) 示例:

        const?arr?=?[1,?20,?-5,?3];
        //沒有初始值:
        console.log(arr.reduce((a,?b)?=>?a?+?b));?//19
        console.log(arr.reduce((a,?b)?=>?a?*?b));?//-300

        //指定初始值:
        console.log(arr.reduce((a,?b)?=>?a?+?b,?1));?//20
        console.log(arr.reduce((a,?b)?=>?a?*?b,?0));?//-0

        8. Promise

        在JavaScript的世界中,所有代碼都是單線程執(zhí)行的。由于這個“缺陷”,導致JavaScript的所有網(wǎng)絡操作,瀏覽器事件,都必須是異步執(zhí)行。異步執(zhí)行可以用回調(diào)函數(shù)實現(xiàn)。一旦有一連串的ajax請求a,b,c,d...后面的請求依賴前面的請求結果,就需要層層嵌套。這種縮進和層層嵌套的方式,非常容易造成上下文代碼混亂,我們不得不非常小心翼翼處理內(nèi)層函數(shù)與外層函數(shù)的數(shù)據(jù),一旦內(nèi)層函數(shù)使用了上層函數(shù)的變量,這種混亂程度就會加劇......總之,這
        層疊上下文的層層嵌套方式,著實增加了神經(jīng)的緊張程度。
        案例:用戶登錄,并展示該用戶的各科成績。在頁面發(fā)送兩次請求:

        1. 查詢用戶,查詢成功說明可以登錄
        2. 查詢用戶成功,查詢科目
        3. 根據(jù)科目的查詢結果,獲取去成績

        分析:此時后臺應該提供三個接口,一個提供用戶查詢接口,一個提供科目的接口,一個提供各科成績的接口,為了渲染方便,最好響應json數(shù)據(jù)。在這里就不編寫后臺接口了,而是提供三個json文件,直接提供json數(shù)據(jù),模擬后臺接口:

        user.json:
        {
        ??"id":?1,
        ??"name":?"zhangsan",
        ??"password":?"123456"
        }
        user_corse_1.json:
        {
        ??"id":?10,
        ??"name":?"chinese"
        }
        corse_score_10.json:
        {
        ??"id":?100,
        ??"score":?90
        }
        //回調(diào)函數(shù)嵌套的噩夢:層層嵌套。
        $.ajax({
        ????url:?"mock/user.json",
        ????success(data)?{
        ????????console.log("查詢用戶:",?data);
        ????????$.ajax({
        ????????????url:`mock/user_corse_${data.id}.json`,
        ????????????success(data){
        ?????????????console.log("查詢到課程:",?data);
        ????????????????$.ajax({
        ????????????????????url:`mock/corse_score_${data.id}.json`,
        ????????????????????success(data)?{
        ????????????????????????console.log("查詢到分數(shù):",?data);
        ????????????????????},
        ????????????????????error(error)?{
        ?????????????????????console.log("出現(xiàn)異常了:"?+?error);
        ????????????????????}
        ????????????????});
        ????????????},
        ????????????error(error){
        ?????????????console.log("出現(xiàn)異常了:"?+?error);
        ????????????}
        ????????});
        ????},
        ????error(error){
        ????????console.log("出現(xiàn)異常了:"?+?error);
        ????}
        });

        我們可以通過Promise解決以上問題。

        Promise語法

        const?promise?=?new?Promise(function(resolve,?reject)?{
        ?//執(zhí)行異步操作
        ????if(/*異步操作成功*/)?{
        ????????resolve(value);?//調(diào)用resolve,代表Promise將返回成功的結果
        ????}?else?{
        ?????reject(error);//調(diào)用reject,代表Promise會返回失敗結果
        ????}
        });


        //使用箭頭函數(shù)可以簡寫為:
        const?promise?=?new?Promise((resolve,?reject)?=>?{
        ????//執(zhí)行異步操作
        ????if(/*異步操作成功*/)?{
        ????????resolve(value);//調(diào)用resolve,代表Promise將返回成功的結果
        ????}?else?{
        ????????reject(error);//調(diào)用reject,代表Promise會返回失敗結果
        ????}
        });

        這樣,在promise中就封裝了一段異步執(zhí)行的結果。

        處理異步結果

        如果我們想要等待異步執(zhí)行完成,做一些事情,我們可以通過promise的then方法來實現(xiàn)。如果想要處理promise異步執(zhí)行失敗的事件,還可以跟上catch:

        promise.then(function(value){
        ????//異步執(zhí)行成功后的回調(diào)
        }).catch(function(error){
        ????//異步執(zhí)行失敗后的回調(diào)
        })

        Promise改造以前嵌套方式

        new?Promise((resolve,?reject)?=>?{
        ????$.ajax({
        ????????url:"mock/user.json",
        ????????success(data){
        ????????????console.log("查詢用戶:",?data);
        ????????????resolve(data.id);
        ????????},
        ????????error(error)?{
        ????????????console.log("出現(xiàn)異常了:"?+?error);
        ????????}
        ????});
        }).then((userId)?=>?{
        ????return?new?Promise((resolve,?reject)?=>?{
        ????????$.ajax({
        ????????????url:`mock/user_corse_${userId}.json`,
        ????????????success(data)?{
        ????????????????console.log("查詢到課程:", data);
        ????????????????resolve(data.id);
        ????????????},
        ????????????error(error)?{
        ????????????????console.log("出現(xiàn)異常了:" + error);
        ????????????}
        ????????});
        ????});
        }).then((corseId)?=>?{
        ????console.log(corseId);
        ????$.ajax({
        ????????url:?`mock/corse_score_${corseId}.json`,
        ????????success(data)?{
        ????????????console.log("查詢到分數(shù):",?data);
        ????????},
        ????????error(error)?{
        ????????????console.log("出現(xiàn)異常了:" + error);
        ????????}
        ????});
        });

        優(yōu)化處理

        優(yōu)化:通常在企業(yè)開發(fā)中,會把promise封裝成通用方法,如下:封裝了一個通用的get請求方法;

        let?get?=?function(url,?data)?{?//實際開發(fā)中會單獨放到common.js中
        ????return?new?Promise((resolve,?reject)?=>?{
        ????????$.ajax({
        ????????????url:url,
        ????????????type:"GET",
        ????????????data:data,
        ????????????success(result)?{
        ????????????????resolve(result);
        ????????????},
        ????????????error(error)?{
        ????????????????reject(error);
        ????????????}
        ????????});
        ????})
        }

        //使用封裝的get方法,實現(xiàn)查詢分數(shù)
        get("mock/user.json").then((result)?=>?{
        ????console.log("查詢用戶:",?result);
        ????return?get(mock/user_corse_${result.id}.json);?
        }).then((result)?=>?{
        ????console.log("查詢到課程:", result);
        ????return?get(mock/corse_score_${result.id}.json)
        }).catch(()?=>?{
        ????console.log("出現(xiàn)異常了:"?+?error);
        });

        通過比較,我們知道了Promise的扁平化設計理念,也領略了這種上層設計帶來的好處。
        我們的項目中會使用到這種異步處理的方式;

        9. 模塊化

        模塊化就是把代碼進行拆分,方便重復利用。類似java中的導包:要使用一個包,必須先導包。而JS中沒有包的概念,換來的是模塊。

        模塊功能主要由兩個命令構成:exportimport

        • export命令用于規(guī)定模塊的對外接口。
        • import命令用于導入其他模塊提供的功能。

        export

        比如我定義一個js文件:hello.js,里面有一個對象

        const?util?=?{
        ????sum(a,?b)?{
        ????return?a?+?b;
        ????}
        }

        我可以使用export將這個對象導出:

        const?util?=?{
        ????sum(a,?b)?{
        ????????return?a?+?b;
        ????}
        }

        export?{util};

        當然,也可以簡寫為:

        export?const?util?=?{
        ????sum(a,?b)?{
        ????return?a?+?b;
        ????}
        }

        export不僅可以導出對象,一切JS變量都可以導出。比如:基本類型變量、函數(shù)、數(shù)組、對象。
        當要導出多個值時,還可以簡寫。比如我有一個文件:user.js:

        省略名稱 上面的導出代碼中,都明確指定了導出的變量名,這樣其它人在導入使用時就必須準確寫出變量名,否則就會出錯。
        因此js提供了default關鍵字,可以對導出的變量名進行省略
        例如:

        //無需聲明對象的名字
        export?default?{
        ????sum(a,?b)?{
        ????return?a?+?b;
        ????}
        }

        這樣,當使用者導入時,可以任意起名字

        import

        使用export命令定義了模塊的對外接口以后,其他JS文件就可以通過import命令加載這個模塊。

        例如我要使用上面導出的util:

        //導入util
        import?util?from?'hello.js'
        //調(diào)用util中的屬性
        util.sum(1,?2)

        要批量導入前面導出的name和age:

        import?{name,?age}?from?'user.js'
        console.log(name?+?",?今年"?+?age?+?"歲了")

        但是上面的代碼暫時無法測試,因為瀏覽器目前還不支持ES6的導入和導出功能。除非借助于工具,把ES6的語法進行編譯降級到ES5,比如Babel-cli工具

        文章已上傳gitee https://gitee.com/codingce/hexo-blog
        項目地址github: https://github.com/xzMhehe/codingce-java



        ?
        更多推薦內(nèi)容

        ↓↓↓

        SpringBoot整合RabbitMQ 實現(xiàn)五種消息模型

        IK分詞器詳解

        打工與創(chuàng)業(yè)殘忍的區(qū)別

        以上,便是今天的分享,希望大家喜歡,覺得內(nèi)容不錯的,歡迎「分享」「」或者點擊「在看」支持,謝謝各位。

        瀏覽 50
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
          
          

            1. 天天躁日日躁狠狠躁白人 | 麻豆视频免费观看 | 国产一级婬乱 | 亭亭五月天操逼视频 | 五月丁香激情综合久久 |