1. 程式人生 > 實用技巧 >ES6中,class , iterator,generator ,物件的擴充套件,嚴格模式,陣列的擴充套件,遞迴實現深拷貝

ES6中,class , iterator,generator ,物件的擴充套件,嚴格模式,陣列的擴充套件,遞迴實現深拷貝

一、class

語法:class是建構函式的語法糖

      class Cat {

            constructor(name) { // 本身方法

                this.name = name;

            };

            run() { // 原型方法

                console.log(this.name + "running")

            };

        };

        let cat1 = new Cat("小花");

        console.log(cat1);

  1. 注意不需要return,如果是基本型別值不會輸出,如果是引用型別改變;
  2. constructor和 方法都是在原型上面;
  3. 瞭解:class 有一個getter函式和setter函式:

     class Cat {

            get name() {

                return "小黑";

            };

 

            set name(val) {

                console.log(val);

            };

        };

 

        let cat1 
= new Cat(); console.log(cat1); cat1.name = "hello";

注: 不使用constructor可以省略不寫;

靜態和例項(成員):

例項方法和例項屬性(成員方法和屬性)必須通過用例項化進行呼叫;

靜態屬性和方法:通過類進行呼叫;

1.繼承:

1)語法: extends關鍵字

    class Parent {

            constructor(name) {

                this.name = name;

            };

            fn() {

                console.log(
"fn"); }; };

classchildrenextendsParent{

// 預設省略可以省略constructor

    constructor(x,color){


  super(x) ; //呼叫父類的constructor方法


  this.color=color;


};


};


letc1=newchildren("小花");


console.log(c1);


c1.fn();

2)手動在子類新增constructor,必須在construtorsuper();

3)Super 方法和屬性:

Super方法:呼叫父類的constructor方法;

Super屬性:在子類裡面,呼叫父類的屬性和方法;

二、iterator

  1. 概念:在集合的資料結構中,陣列,物件,setmap 需要統一介面,來進行處理。Iterator就是這個機制,為不同的資料結構提供統一的介面,任何的資料結構,只要部署了iterator就可以進行迴圈遍歷。
  2. 作用:1.提供統一介面,2.按照一定的順序迴圈遍歷,3.for...of...提供消費
  3. 目的:提供統一介面
  4. 模擬iterator介面:

        let arr = ["a", "b", "c"];

        function myIterator(arr) {

            let index = 0;

            return {

                next() {

                    // if (index < arr.length) {

                    //     return {

                    //         value: arr[index++],

                    //         done: false

                    //     }

                    // } else {

                    //     return {

                    //         value: undefined,

                    //         done: true

                    //     }

                    // };

 

                    return index < arr.length ? {

                        value: arr[index++],

                        done: false

                    } : {

                        value: undefined,

                        done: true

                    };

                };

            };

        };

        let x = myIterator(arr);

        console.log(x.next());  // {value: "a", done: false}

        console.log(x.next());  // {value: "b", done: false} 

        console.log(x.next());   // {value: "c", done: false} 

        console.log(x.next()) ;   // {value: undifined, done: true} 

1.建立的是一個指標物件,指向當前資料結構的起始位置

2.第一次呼叫next指向的是第一個位置的元素

3.第二次呼叫next指向的是第二個位置的元素

4.一直指向到結束位置;

注意:donefalse表示可以繼續迴圈遍歷,donetrue表示迴圈遍歷結束;

5.預設的 Iterator 介面部署在資料結構的Symbol.iterator屬性;

  obj[Symbol.iterator] = function() {

            let index = 0;

            return {

                next: () => {

                    // console.log(Object.keys(this).length)

                    // console.log(Object.keys(this)[index]) // 取屬性

                    // console.log(this) //物件

                    // console.log(this[Object.keys(this)[index]]) // 取值

 

                    if (index < Object.keys(this).length) {

                        return {

                            value: this[Object.keys(this)[index++]],

                            done: false

                        }

                    } else {

                        return {

                            value: undefined,

                            done: true

                        }

                    }

                }

            }

        }

三、Generator

1.概念:

解決非同步程式設計方法;

是一個狀態機,可以從函式的內部返回多個狀態

返回的是一個iterator物件

2.語法

1)function和函式名中間寫一個*

2)返回的是一個iterator物件,通過呼叫next()來獲取值

3)通過yield可以在函式的外部返回多個狀態,狀態機

4)因為返回的是一個iterator物件,所以可以使用for...of...

5)注意:可以使用return,但是return返回done:true;表示迴圈遍歷已經結束;

for...of...迴圈是拿不到return後面的值;

6)Yield有阻塞程式碼執行,必須呼叫next方法之後,才可以執行;

       function * fn(){
            console.log(fn());  
            let aa = 8;
            console.log(aa);
            yield 'hello';
            yield 2 + 1;
            let a = yield 4;
            // let b;
            console.log(a);
            let b = yield 12;
            return b;
        }
        let g = fn();
        console.log(g.next()); //  fn{<suspended>}    8    {value: "hello", done: false}
        console.log(g.next());  //  {value: 3, done: false}
        console.log(g.next());   // {value: 4, done: false}
        console.log(g.next(9));  //  9     {value: 12, done: false}
        console.log(g.next(10));  // {value: 10, done: true}

四、擴充套件內容:

1. 物件的擴充套件

       let obj = {
            a: 1,
            b: 2
        };
        console.log(Object.getOwnPropertyDescriptor(obj, "a")); // {value: 1, writable: true, enumerable: true, configurable: true}

        Object.defineProperty(obj,'a',{
            // value: 'hello',
            writable : false,  // 是否可修改值
            enumerable: false, //是否可遍歷
            configurable: false // 是否可設定

        });
        obj.a = 'www';
        console.log(obj.a);   //   1
        for(let key in obj){
            console.log(key);   //  b
        };
        console.log(Object.values(obj));   // [2]

2. 嚴格模式:

注意:"use strict"; 必須放在js檔案的第一行或者是函式的第一行;

2.1 變數必須先宣告,再使用

2.2 This不允許指向全域性物件,返回的是undefined

2.3 關於arguments

2.4 對於只讀屬性,不能夠重新賦值

  <script>
'use strict' // this不允許指向全域性物件 function fn1(){ console.log(this); }; fn1(); // undifined // 不允許arguments重新賦值 function fn2(){ console.log(arguments); // Arguments(4)[1, 2, 3, 4, callee: (...), Symbol(Symbol.iterator): ƒ] console.log(Array.prototype.slice.call(arguments)); // (4)[1, 2, 3, 4] // arguments = 'hello'; // console.log(arguments); //會報錯 } fn2(1,2,3,4); // 不再追蹤引數的變化 function fn3(num){ num++; console.log(arguments); // Arguments(3)[2, 3, 4, callee: (...), Symbol(Symbol.iterator): ƒ] }; fn3(2,3,4); // 不允許使用callee function fn4(){ console.log(arguments.callee);// 獲取的是函式本身 }; // fn4(); // 不允許修改物件的只讀屬性,否則會報錯 let obj = { a : 10 }; Object.defineProperty(obj,'a',{ // writable: false, configurable: false, enumerable: false }); obj.a = 'hello'; console.log(obj); // {a: "hello"} </script>

3. 陣列擴充套件:

Array.of() 將一組值轉為一個數組,彌補Array建構函式的不足

find() 返回第一個符合條件的元素;

findIndex() 返回第一個符合條件的元素的下標

Includes() 不僅可以在陣列中使用,也可以在字串中使用;判斷一個元素是否存在,返回的是一個布林值;

 <script>
        let arr = new Array(5);
        console.log(arr); //(5)[empty × 5]

        let arr1 = [5];
        console.log(arr1);  //[5]

        let arr2 = Array.of(12, 24, 34);
        console.log(arr2);  // (3)[12, 24, 34]

        let arr3 = [1, 2, 3, 4, 5, 6, 7];
        let x = arr3.find((item, index, array) => {
            // console.log(item,index,array);
            return item > 3;
        });
        console.log(x);  // 4

        let x2 = arr3.findIndex(item => item > 3);
        console.log(x2);  // 3

        console.log(arr3.includes('hello')); //false
        console.log(arr3.includes(4));  // true

        let str = 'hello';
        console.log(str.includes('hello'));  // true
        console.log(str.includes('he'));   // true
    </script>

深拷貝:

遞迴實現深拷貝:

      let obj = {
            a: 1,
            b: 'hello',
            c: undefined,
            arr: [12, 34],
            ob: { ha: 'haha' },
            fn: function () {
                console.log('fn');
            }
        };
        let copy = JSON.parse(JSON.stringify(obj));  // 不能拷貝undefined和函式
        console.log(copy);

        // 遞迴實現深拷貝
        function deepCopy(obj, newObj = {}) {
            for (let key in obj) {
                if (typeof obj[key] === 'object') {
                    newObj[key] = Array.isArray(obj[key]) ? [] : {};
                    deepCopy(obj[key], newObj[key]);
                } else {
                    newObj[key] = obj[key];
                };
            };
            return newObj;
        };

        let dc = deepCopy(obj);
        dc.arr[0] = 3;
        console.log(dc, obj);