1. 程式人生 > >ES6學習總結

ES6學習總結

one extend -- -m 鏈式調用 str 可變 expand 兩個

  1、ES6的產生

  JavaScript 是一個持續演進的編程語言,並由瀏覽器廠商、開發者和社區成員組成的委員會制定標準。委員會引入了JavaScript歷史上的最大更新 ES6 (ES2016),而 ES7 是年度更新的第一版(ES2017)。

  2、ES6ES7優點

    • 簡化常見編程模式

    • 使代碼更容易編寫以及定制底層的 JavaScript 行為。

  3、新特性

    • Class 可以讓開發者更容易地編寫面向對象程序,並安全地擴展extend JavaScript內建對象。

    • 箭頭函數Arrow functions、默認參數default parameters

      和數組的遍歷方法array convenience methods使得常用功能更容易編寫,而不需要在項目之間復制黏貼代碼。

    • JavaScript 的異步處理流和嵌套回調讓人難以理解,所以 ES6 中引入了promises 、叠代器和生成器iterators, and generators以簡化異步代碼,讓控制流更直觀而不易出錯。

  4、ES6基礎---let命令

    • 用於聲明(局部)變量,類似於var(全局),但是聲明的變量只在let命令所在的代碼塊有效。
    • 創建塊級作用域(下面詳細介紹)

      1 if(true){
      2     let a=10;
      3     var
      b=1; 4 } 5 console.log(a); //Uncaught ReferenceError: a is not defined 6 console.log(b); //1
    • 沒有變量提升

      1 console.log(typeof str);     //undefined
      2 var str = 10;     
      3 
      4 console.log(typeof abc);     //Uncaught ReferenceError: abc is not defined
      5 let abc = 10;
    • 不允許重復聲明

      1
      let a=10; 2 let a=20; 3 console.log(a); //Uncaught SyntaxError: Identifier ‘b‘ has already been declared 4 5 var a=10; 6 var a=20; 7 console.log(a); //20
    • 暫時性死區

      在塊級作用域中使用let聲明變量時,塊級作用域會形成一個封閉的環境,不能訪問外部聲明的變量

      1 var c = 19;
      2 if(true) {
      3       console.log(c);
      4       let c;     //Uncaught ReferenceError: c is not defined
      5 }

  5、為什麽需要塊級作用域?

  ES5 只有全局作用域和函數作用域,沒有塊級作用域,這帶來很多不合理的場景。

    • 第一種場景----內層變量可能會覆蓋外層變量。
      1 var tmp = hi;
      2 function f() {
      3      console.log(tmp);        //這裏想使用外層的tmp=‘hi‘
      4      if (false) {            //if代碼塊之內使用內層的tmp=‘hello‘
      5         var tmp = hello;
      6      }
      7 }
      8 f();     //但是輸出結果是undefined,因為這裏存在變量提升,導致內部tmp覆蓋了外層的tmp
    • 第二種場景----用來計數的循環變量泄露為全局變量。
      1 var s = hello;
      2 for (let i = 0; i < s.length; i++) {
      3       console.log(s[i]);
      4 }
      5 console.log(i);     // 5  
      6 //上面代碼中,變量i只用來控制循環,但是循環結束後,它並沒有消失,泄露成了全局變量

  6、ES6基礎---const命令

  const聲明一個只讀的常量

    • 旦聲明,常量的值就不能改變

      1 const PI = 3.1415;        // 3.1415
      2 PI = 3;                    // TypeError: Assignment to constant variable.
    • 只聲明,不賦值,也會報錯

      1 const a;        // SyntaxError: Missing initializer in const declaration
    • let相同,只在聲明的塊級作用域中有效

      1 if (true) {
      2      const a = 5;
      3 }
      4 console.log(a);        // Uncaught ReferenceError: a is not defined
    • 不允許重復聲明
      1 var message = "Hello!";
      2 let age = 25;
      3 
      4 // 以下兩行都會報錯
      5 const message = "Goodbye!";
      6 const age = 30;
    • 也沒有變量提升,存在暫時性死區
      1 if (true) {
      2      console.log(a);     //Uncaught ReferenceError: a is not defined
      3      const a = 5;
      4 }

  7、ES6 聲明變量的六種方法

    • ES5 只有兩種聲明變量的方法:var命令和function命令。
    • ES6除了添加letconst命令,另外兩種聲明變量的方法:import命令和class命令。所以,ES6 一共有6種聲明變量的方法。

  8、箭頭函數

    • ES6 允許使用“箭頭”(=>)定義函數。
      1 var f = v => v;
    • 上面箭頭函數等同於
      1 var f = function(v) {  return v;};
    • 引入箭頭函數的兩個作用
      • 更簡短的函數書寫,簡化回調函數
        1 // 正常函數寫法
        2 [1,2,3].map(function (x) {
        3   return x * x;
        4 });
        5 // 箭頭函數寫法
        6 [1,2,3].map(x => x * x);
      • 對this的詞法解析,自己內部沒有this
    • 使用時需註意
      • 函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象。
      • 不可以當作構造函數,也就是說,不可以使用new命令,否則會拋出一個錯誤。
      • 不可以使用arguments對象,該對象在函數體內不存在。如果要用,可以用 rest 參數代替。
      • 不可以使用yield命令,因此箭頭函數不能用作 Generator 函數
        1 //this對象的指向是可變的,但是在箭頭函數中,它是固定的。
        2 function foo() {
        3   setTimeout(() => {
        4     console.log(id:, this.id);
        5   }, 100);
        6 }
        7 var id = 21;
        8 foo.call({ id: 42 });       // id: 42
        9 //箭頭函數可以讓setTimeout裏面的this,綁定定義時所在的作用域,而不是指向運行時所在的作用域
    • 小測試:請問下面的代碼中有幾個this?
       1 function foo() {
       2   return () => {
       3     return () => {
       4       return () => {
       5         console.log(id:, this.id);
       6       };
       7     };
       8   };
       9 }
      10 
      11 var f = foo.call({id: 1});
      12 
      13 var t1 = f.call({id: 2})()();     // id: 1
      14 var t2 = f().call({id: 3})();     // id: 1
      15 var t3 = f()().call({id: 4});     // id: 1

  上面代碼之中,只有一個this,就是函數foothis,所以t1t2t3都輸出同樣的結果。因為所有的內層函數都是箭頭函數,都沒有自己的this,它們的this其實都是最外層foo函數的this

  除了this,以下三個變量在箭頭函數之中也是不存在的,指向外層函數的對應變量:argumentssupernew.target

  9、promise對象

    • 異步編程的一種解決方案
      • 避免了層層嵌套的回調函數,使用鏈式調用方式來組織代碼,更加直觀
      • 提供統一的接口,使得控制異步操作更加容易。
    • 三種狀態
      • Pending進行中
      • Resolved已完成(又稱Fulfilled)
      • Rejected已失敗
    • 基本用法
       1 //創造一個promise實例
       2 var promise = new Promise(function(resolve, reject) {
       3   // ... some code
       4 
       5   if (/* 異步操作成功 */){
       6     resolve(value);
       7   } else {
       8     reject(error);
       9   }
      10 });
      11 //實例生成後,可以用then方法分別指定Resolved狀態和Reject狀態的回調函數。
      12 promise.then(function(value) {
      13   // success
      14 }, function(error) {
      15   // failure
      16 });
    • promise.all()
      • 用於將多個 Promise 實例,包裝成一個新的 Promise 實例。

        var p = Promise.all([p1, p2, p3]);
      • p的狀態由p1p2p3決定,分成兩種情況。

        (1)只有p1p2p3的狀態都變成fulfilledp的狀態才會變成fulfilled,此時p1p2p3的返回值組成一個數組,傳遞給p的回調函數。

        (2)只要p1p2p3之中有一個被`rejected`,p的狀態就變成rejected,此時第一個被reject的實例的返回值,會傳遞給p的回調函數。

         1 // 生成一個Promise對象的數組
         2 var promises = [2, 3, 5, 7, 11, 13].map(function (id) {
         3   return getJSON(/post/ + id + ".json");
         4 });
         5 ?
         6 Promise.all(promises).then(function (posts) {
         7   // ...
         8 }).catch(function(reason){
         9   // ...
        10 });
        //上面代碼中,promises是包含6個 Promise 實例的數組,只有這6個實例的狀態都變成fulfilled,或者其中有一個變為rejected,才會調用Promise.all方法後面的回調函數

  先到這裏吧!有什麽不對的地方望大家多多指點!


ES6學習總結