ES6學習筆記(第二講)

一、單體模式下的對象

以前咱們定義一個對象,使用的語法格式以下所示:html

<script>
        var name = 'qianqian';
        var age = 24;
        var person = {
            name:name,
            age:age,
            showName:function(){
                console.log(this.name);
            }
        };
        person.showName();
    </script>

在ES6當中聲明定義一個對象的語法簡潔化了。在ES6的對象語法當中,若是對象的屬性名和屬性值變量名相同,則只使用一個變量名便可,即便用name來代替name:name的寫法。對象的方法定義能夠從方法名:function(){}改成方法名(){}的寫法。ES6當中單體模式下對象聲明的語法格式以下所示:前端

<script>
        let name = 'qianqian';
        let age = 24;
        let person = {
            name,
            age,
            showName(){
                console.log(this.name);
            }
        };
        person.showName();
    </script>

這兩種寫法的運行結果相同,均爲輸出qianqiannode

二、面向對象(class 和 constructor)

以前在面向對象當中類和構造函數的概念區分並不明顯。示例代碼以下所示:jquery

<script>
        //定義一個構造函數(類),在裏面定義類的屬性
        function Person(name,age){
            this.name = name;
            this.age = age;
        };
        //使用prototype定義類的方法
        Person.prototype.showName = function(){
            console.log(this.name);
        };
        //使用new來調用聲明好的類,傳入不一樣的實參來造成不一樣的實例對象。
        var p1 = new Person('qianqian',24);
        p1.showName();
    </script>

在ES6當中,類(class)和構造函數(constructor)的概念被區分開了。ES6當中使用面向對象的語法來定義一個類的示例代碼以下所示:git

<script>
        //使用關鍵字class來定義一個Person類,在內部定義其屬性與方法
        class Person{
            //在構造函數當中定義類的屬性
            constructor(name,age){
                this.name = name;
                this.age = age;
            };
            //接下去分別定義類的方法,不須要再使用prototype
            showName(){
                console.log(this.name);
            };
        };
        //使用new來調用聲明好的類,傳入不一樣的實參,來生成不一樣的實例對象
        let p1 = new Person('qianqian',24);
        p1.showName();
    </script>

Person這個類生成的實例對象,都有一個默認的constructor屬性,其屬性值均爲類名Person。示例代碼以下所示:github

<script>
        class Person{
            constructor(name,age){
                this.name = name;
                this.age = age;
            };
            showName(){
                console.log(this.name);
            };
        };
        let p1 = new Person('qianqian',24);
        let p2 = new Person('meimei',23);
        console.log(p1.constructor == Person);
        console.log(p2.constructor == Person);
        console.log(p1.showName == p2.showName);
    </script>

其輸出結果均爲trueajax

三、原型繼承

假設有一個子類Worker類要繼承父類Person類,在以前的面向對象的語法當中,咱們在Worker類的構造函數當中,使用Person.apply(this,arguments);來完成對父類屬性的繼承。使用Worker.prototype = new Person();來實現對父類方法的繼承。示例代碼以下所示:json

<script>
        function Person(name,age){
            this.name = name;
            this.age = age;
        };
        Person.prototype.showName = function(){
            console.log(this.name);
        };
        function Worker(name,age){
            Person.apply(this,arguments);
        };
        //實現方法繼承的語法格式爲:子類.prototype = new 父類();
        Worker.prototype = new Person();
        //完成繼承後,使用Worker類來生成實例
        var w1 = new Worker('qianqian',24);
        w1.showName();
    </script>

輸出結果爲qianqianbootstrap

apply方法只接收兩個參數,其中第二個參數必須是一個數組或者類數組,故能夠將當前函數的arguments對象做爲apply函數的第二個參數傳入。apply方法改變的是函數的調用對象,此方法的第一個參數爲改變後調用這個函數的對象。數組

而在ES6當中,實現原型繼承的語法就相對簡化了許多,咱們使用class 子類 extends 父類{};便可完成子類繼承父類所有屬性和方法的功能。咱們能夠給繼承的子類對象隨意添加新的方法,但若是想要給子類添加新的屬性,在其構造函數的內部,使用super(父類的形參列表);先調用一次父類的構造函數,避免覆蓋父類的構造函數,而後再定義新的子類屬性。示例代碼以下所示:

<script>
        class Person{
            constructor(name,age){
                this.name = name;
                this.age = age;
            };
            showName(){
                console.log(this.name);
            };
        };
        class Worker extends Person{
            constructor(name,age,job){
                //至關於先調用一次父類的構造函數,防止覆蓋父類的構造函數
                super(name,age);
                //再定義新的子類屬性
                this.job = job;
            };
            //能夠隨意給子類對象添加新的方法
            showName(){
                console.log(this.name);
            };
            showJob(){
                console.log(this.job);
            };
        };
        //調用子類生成實例對象
        let w1 = new Worker('qianqian',24,'student');
        w1.showName();
        w1.showJob();
    </script>

輸出結果爲qianqianstudent

四、模塊化

ES6自帶模塊化,不過咱們在使用ES6的這個新語法特性時,必須引入編譯文件,由於瀏覽器端尚未徹底支持。好比咱們定義一個模塊a.js(通常一個js文件即表明一個模塊),在其內部定義了變量和函數以後,可使用export default {變量名,函數名};的方式來導出。a.js的示例代碼以下所示:

let a = 5;
function sum(){
    return 'haha';
};
export default {a,sum};

咱們在主文件index.html當中使用import 自定義模塊名 from '模塊文件的相對路徑';來實現模塊的導入。其中index.html的示例代碼以下所示:

<script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script>
    <script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script>
    <script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script>
    <script type="module">  
        import A from './a.js';
        console.log(A.a);
        console.log(A.sum());
    </script>

若第一次運行報以下錯誤:

圖片描述

是由於咱們沒有把項目文件放在服務器環境下運行。

輸出結果爲5haha

五、Promise 對象

promise是ES6當中一個新的語法點,這個對象主要用來傳遞和處理異步操做的數據。promise對象只有三種狀態:pending(等待)、resolve(成功)、reject(失敗),而且其狀態變化只能是從pendingresolve,或者是從pendingreject。其基本使用語法的示例代碼以下所示:

<script>  
        //通常在異步操做回調函數當中,聲明一個Promise對象
        let p1 = new Promise(function(resolve,reject){
            if(異步操做成功){
                resolve(成功的數據);
                //把成功的數據傳遞下去
            }else{
                reject(失敗的緣由);
                //把失敗的緣由傳遞下去
            };
        });
        //promise對象p1具備then方法,接收兩個函數參數,該方法仍然返回promise對象
        p1.then(function(value){
            /*當p1的回調函數當中執行resolve(成功的數據)時,執行該函數,形參value接收由resolve傳遞下來的成功的數據。*/
        },function(err){
            /*當p1的回調函數當中執行reject(失敗的緣由)時,執行該函數,形參err接收由reject傳遞下來的失敗的緣由。*/
        });
    </script>

咱們在前端使用ajax異步操做數據時,可使用promise對象,示例代碼以下所示:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
    <script src="jquery-1.10.2.js"></script>
    <script>  
       $(function(){
               $('#btn').on('click',function(){
                   let p1 = new Promise(function(resolve,reject){
                       $.ajax({
                           url:'http://localhost/demo/1.txt',
                           type:'GET',
                           dataType:'text',
                           success:function(data){
                               resolve(data);
                           },
                           error:function(){
                               reject('failed');
                           }
                       });
                   });
                   p1.then(function(value){
                       console.log(value);
                   },function(err){
                       console.log(err);
                   });
               });
       });
    </script>  
</head>
<body>
    <button id="btn">button</button>
</body>
</html>

咱們也能夠在node.js的異步操做的回調函數當中使用promise對象。示例代碼以下所示:

'use strict';
const fs = require('fs');
const path = require('path');
let target = path.join(__dirname,'./1.txt');
fs.readFile(target,function(err,data){
    let p1 = new Promise(function(resolve,reject){
        if(err){
            reject(err);
        }else{
            resolve(data);
        };
    });
    p1.then(function(data){
        console.log(data.toString());
    },function(err){
        console.log(err);
    });
});
5.一、promise對象的方法

一、 .then()

該方法在前面有詳細介紹,其示例代碼以下所示:

<script>  
     let p1 = new Promise(function(resolve,reject){
         resolve(1);
     });
     p1.then(function(value){
         alert(value);
         return value + 1;
     },function(value){
         alert(value);
         return value + 2;
     }).then(function(value){
         alert(value);
     });
</script>

先彈出1,再彈出2

二、.catch()

該方法用於捕獲異常信息。其示例代碼以下所示:

<script>  
         let p1 = new Promise(function(resolve,reject){
             resolve(1);
         });
         p1.then(function(value){
             throw value;
         }).catch(function(e){
             alert(e);
         });
    </script>

輸出結果爲彈出數字1

5.二、Promise類身上的方法

一、 Promise.resolve()

這個方法能夠生成一個成功的promise對象。該方法的參數能夠是一個單純的值或數組,也能夠是另外一個promise的執行結果。示例代碼以下所示:

<script>  
         let p1 = Promise.resolve([1,2,3]);
         p1.then(function(value){
             console.log(value[2]);
         },function(err){
             alert('failed');
         });
    </script>

輸出結果爲3

二、 Promise.reject()

這個方法能夠生成一個失敗的promise對象。示例代碼以下所示:

<script>  
         let p1 = Promise.reject('failed');
         p1.then(function(value){
             alert('success')
         },function(err){
             alert(err);
         });
    </script>

彈出結果爲'failed'

三、 Promise.all()

該方法默認接收一個數組,其中數組元素均爲promise對象。這個方法能夠將多個promise對象組合,包裝成一個全新的promise對象。

這個全新的promise對象也有then方法,當其參數當中全部的promise對象都成功時,纔會執行then方法當中的第一個參數函數,此時該函數的形參表明一個數組,裏面的值按順序出現。示例代碼以下所示:

<script>  
         let p1 = Promise.resolve(1);
         let p2 = Promise.resolve(2);
         let p3 = Promise.resolve(3);
         Promise.all([p1,p2,p3]).then(function(value){
             console.log(value);
         },function(err){
             console.log('failed');
         });
    </script>

其輸出結果爲[1,2,3]

在其參數數組當中只要出現失敗的promise對象,就會執行then方法當中的第二個參數函數,形參僅包含最早出現的那個失敗的promise對象當中的值。示例代碼以下所示:

<script>  
         let p1 = Promise.resolve(1);
         let p2 = Promise.reject(2);
         let p3 = Promise.reject(3);
         Promise.all([p1,p2,p3]).then(function(value){
             console.log('success' + value);
         },function(err){
             console.log('failed' + err);
         });
    </script>

其輸出結果爲'failed2'

四、 Promise.race()

該方法默認接收一個數組,其中數組元素均爲promise對象。這個方法選取最早到達的那個promise結果,該方法的返回結果也爲一個promise對象。示例代碼以下所示:

<script>  
         let p1 = new Promise(function(resolve,reject){
             setTimeout(resolve('one'),50);
         });
         let p2 = new Promise(function(resolve,reject){
             setTimeout(resolve('two'),100);
         });
         Promise.race([p1,p2]).then(function(value){
             console.log(value);
         },function(err){
             console.log(err);
         });
    </script>

其輸出結果爲'one'

六、Generator(生成器)

生成函數與普通函數在語法格式上的區別爲,在函數名前面有*號,通常緊跟在function的後面。在生成器函數的內部,有一種相似與return的語法,關鍵字yieldyield語句能夠用於遍歷函數內部的狀態)。兩者的區別是,普通函數只能return一次,而生成器函數能夠yield屢次。在生成器函數的執行的過程當中,遇到yield表達式當即暫停,後續能夠恢復執行狀態。示例代碼以下所示:

<script> 
        //聲明一個生成器函數show 
         function* show(){
             yield 'hello';
             yield 'world';
             yield 'ES6';
             return 'all';
         };
         //生成器函數先調用一次,用變量res來接收該函數執行的返回值
         let res = show();
         /*這個返回值身上自帶方法.next(),相似於開始進行狀態遍歷,該方法每調用一次,都會返回一個對象,有value和done這兩個屬性,value的屬性值爲每次yield後面對應的值,done的屬性值是一個布爾值,表明狀態遍歷是否結束。*/
         console.log(res.next());
         console.log(res.next());
         console.log(res.next());
         console.log(res.next());
         console.log(res.next());
    </script>

其輸出結果爲:

圖片描述

生成器函數能夠放在對象內部,做爲對象的一個方法。其示例代碼以下所示:

<script> 
        var json1 = {
            *show(){
                yield 'hello';
                yield 'world';
                return 'all';
            }
        };
        var json2 = {
            show:function*(){
                yield 'xixi';
                yield 'haha';
                return 'so';
            }
        };
        var res1 = json1.show();
        console.log(res1.next());
        console.log(res1.next());
        console.log(res1.next());
        var res2 = json2.show();
        console.log(res2.next());
        console.log(res2.next());
        console.log(res2.next());
    </script>

其輸出結果爲:

圖片描述

咱們可使用for...of來循環生成器函數,示例代碼以下所示:

<script> 
        function* show(){
            yield 'hello';
            yield 'world';
            yield 'ES6';
            return 'all';
        };
        for(let v of show()){
            console.log(v);
        };
    </script>

其輸出結果爲:

圖片描述

生成器函數的yield表達式語句自己沒有返回值,或者說老是返回undefinednext()方法能夠帶一個參數,該參數會被當作上一條yield語句的返回值。示例代碼以下所示:

<script> 
        function* show1(){
            let a = yield 'hello';
            return a;
        };
        let res1 = show1();
        console.log(res1.next());
        console.log(res1.next());
        function* show2(){
            let a = yield 'hello';
            return a;
        };
        let res2 = show2();
        console.log(res2.next());
        console.log(res2.next('world'));
        function* show3(){
            for(let i = 0; i < 10; i++){
                let a = yield i;
                if(a){
                    i = -1;
                };
            };
        };
        let res3 = show3();
        console.log(res3.next());
        console.log(res3.next());
        console.log(res3.next(true));
        console.log(res3.next());
    </script>

其輸出結果爲:

圖片描述

相關文章
相關標籤/搜索