ES5、ES6、ES7電子教程

ES5電子教程

中文版:http://yanhaijing.com/es5/#58
英文版:https://people-mozilla.org/~jorendorff/es5.1-final.html

ES6電子教程

中文版:http://es6.ruanyifeng.com/
英文版:http://www.ecma-international.org/ecma-262/6.0/#sec-type
ES6的瀏覽器兼容性問題: https://segmentfault.com/a/1190000005128101

ES7電子教程

英文版:http://www.ecma-international.org/ecma-262/7.0/index.html

名詞解析

(1)鏈接: http://www.jb51.net/article/30719.htm

  • 變量提升
    1、查找變量的順序是:活動對象-->全局對象,一旦找到變量就停止查找
    2、javascrip函數(shù)級作用域的影響,即函數(shù)會創(chuàng)建新的作用域
    3、變量提升,是把變量提升提到函數(shù)的頂部,只提升變量的聲明,賦值沒提升。
   //場景一
    var x = 1; //x存儲在全局對象中
    console.log(x); // 1
    if (true) {
        var x = 2; //x存儲在活動對象中
        console.log(x); //2
    }
    console.log(x);// 2     
   //場景一
    var v='Hello World';
    (function(){
        alert(v); 
        var v='I love you';
        alert(v);
    })(); 
  //定義的三個(gè)變量
  (function(){
      var a='One';
      var b='Two';
      var c='Three';
  })();
  //實(shí)際上是這樣子的:
  (function(){
      var a,b,c;
      a='One';
      b='Two';
      c='Three';
  })();
  所以在定義js變量時(shí)候,需要把變量放在塊級作用域的頂端,先定義變量,以防出現(xiàn)錯(cuò)誤。
  • 函數(shù)提升
    1、函數(shù)提升:就是把函數(shù)聲明提到作用域的頂部
    2、函數(shù)有兩種表達(dá)方式:函數(shù)聲明方式和函數(shù)表達(dá)方式
    3、只有函數(shù)聲明方式才能提升
  //函數(shù)聲明方式
    function myTest(){
        foo();
        function foo(){
            alert("我來自 foo");
        }
    }
    myTest(); 
 //函數(shù)表達(dá)方式
    function myTest(){
        foo();
        var foo =function foo(){
            alert("我來自 foo");
        }
    }
    myTest();
  • ** 暫時(shí)性死區(qū)**
    只要一進(jìn)入當(dāng)前作用域,所要使用的變量就已經(jīng)存在,但是不可獲取,只有等到聲明變量的那一行代碼出現(xiàn),才可以獲取和使用該變量。
  • ** let與var區(qū)別**
    //不同之處
    1、let聲明的變量只在let所在的代碼塊內(nèi)有效
    2、var有變量提升,則聲明之前使用不會報(bào)錯(cuò);let沒有變量提升,聲明前使用會報(bào)錯(cuò)
    3、let存在暫時(shí)性死區(qū),只要塊級作用域內(nèi)存在let命令,它所聲明的變量就“綁定”(binding)這個(gè)區(qū)域,不再受外部的影響
       var tmp = 123;
       if (true) {
            tmp = 'abc'; // ReferenceError 
            let tmp;
       }
   4、ES6規(guī)定,若區(qū)塊中存在let和const命令,這個(gè)區(qū)塊對這些命令聲明的變量,從一開始就形成了封閉作用域。凡在聲明前就使用這些變量,均報(bào)錯(cuò)。
   5、ES6規(guī)定暫時(shí)性死區(qū)和let、const語句不出現(xiàn)變量提升,主要是為了減少運(yùn)行時(shí)錯(cuò)誤。
   6、let不允許在相同作用域內(nèi),重復(fù)聲明同一個(gè)變量
  • ** 塊級作用域**
    ES5只有全局作用域和函數(shù)作用域,沒有塊級作用域,這帶來很多不合理的場景
   1、避免由于變量提升,內(nèi)層變量可能會覆蓋外層變量;
   2、避免用來計(jì)數(shù)的循環(huán)變量泄露為全局變量;
   3、ES6允許塊級作用域的任意嵌套, 外層作用域無法讀取內(nèi)層作用域的變量, 內(nèi)層作用域可以定義外層作用域的同名變量;
       {{{{{let insane = 'Hello World'}}}}};
       {{{{ {let insane = 'Hello World'} console.log(insane); // 報(bào)錯(cuò)}}}};
       {{{{ let insane = 'Hello World'; {let insane = 'Hello World'}}}}};
   4、塊級作用域可以替代立即執(zhí)行的匿名函數(shù)的功能
   5、ES5(嚴(yán)格模式)規(guī)定,函數(shù)只能在頂層作用域和函數(shù)作用域之中聲明,不能在塊級作用域聲明
   6、ES6允許在塊級作用域之中聲明函數(shù),只在大括號情況下可行,沒有大括號會報(bào)錯(cuò);函數(shù)聲明類似于var,存在函數(shù)提升
   注意:環(huán)境導(dǎo)致的行為差異太大,應(yīng)該避免在塊級作用域內(nèi)聲明函數(shù)。 若需要,也應(yīng)該寫成函數(shù)表達(dá)式,而不是函數(shù)聲明語句
  • ** 頂層對象及其屬性**
    根據(jù)不同環(huán)境,頂層對象指:
    1、瀏覽器:window、self對象。有實(shí)體含義,即指代瀏覽器的窗口對象
    2、node: global對象
  ES5中,頂層對象的屬性與全局變量等價(jià),這是javascript語言設(shè)計(jì)的最大敗筆之一,原因:
  1、沒法在編譯時(shí)就報(bào)出變量未聲明的錯(cuò)誤,只有運(yùn)行時(shí)才能知道。因?yàn)槿肿兞靠赡苁琼攲訉ο蟮膶傩詣?chuàng)造的,而屬性的創(chuàng)造是動態(tài)的。
  2、頂層對象到處可讀,不利于模塊化編程
  3、人為創(chuàng)造全局變量
  ES6中,對頂層對象及其屬性做了以下處理:
  1、保留var和function命令,其定義的全局變量依然為頂層對象的屬性
  2、let、const、import、class四種命令定義的全局變量不屬于頂層對象的屬性
  使用this對象獲取頂層對象,但具有一定局限性:
  1、全局環(huán)境中,this會返回頂層對象。
     但是,Node模塊和ES6模塊中,this返回的是當(dāng)前模塊。
  2、函數(shù)里面的this,如果函數(shù)不是作為對象的方法運(yùn)行,而是單純作為函數(shù)運(yùn)行,this會指向頂層對象。
     但是,嚴(yán)格模式下,這時(shí)this會返回undefined。
  3、不管是嚴(yán)格模式,還是普通模式,new Function('return this')(),總是會返回全局對象。
     但是,如果瀏覽器用了CSP(Content Security Policy,內(nèi)容安全政策),那么eval、new Function這些方法都可能無法使用
   在所有情況下,都取到頂層對象的方法:
    //方法一:
    (typeof window !== 'undefined'
       ? window
       : (typeof process === 'object' &&
          typeof require === 'function' &&
          typeof global === 'object')
         ? global
         : this);
    //方法二:
    var getGlobal = function () {
      if (typeof self !== 'undefined') { return self; }
      if (typeof window !== 'undefined') { return window; }
      if (typeof global !== 'undefined') { return global; }
      throw new Error('unable to locate global object');
    };   
  • 解構(gòu)(Destructuring)賦值
    從數(shù)組或?qū)ο笾刑崛≈?,按照對?yīng)位置,對變量賦值
  解構(gòu)賦值類型:
  1、數(shù)組形式:數(shù)據(jù)結(jié)構(gòu)具有Iterator接口.
        var:  var [v1, v2, ..., vN ] = array;
        let:   let [v1, v2, ..., vN ] = array;
        const:  const [v1, v2, ..., vN ] = array;
        Set結(jié)構(gòu):  let [x, y, z] = new Set(["a", "b", "c"]);
        function* fibs() {
          var a = 0;
          var b = 1;
          while (true) {
            yield a;
            [a, b] = [b, a + b];
          }
        }
        var [first, second, third, fourth, fifth, sixth] = fibs();    
       // fibs是一個(gè)Generator函數(shù),原生具有Iterator接口。解構(gòu)賦值會依次從這個(gè)接口獲取值                            
  2、對象形式:對象解構(gòu)賦值與數(shù)組解構(gòu)賦值的區(qū)別:
      * 數(shù)組的元素按次序排序,變量的值與位置有關(guān);左邊變量在右邊的值可以不賦值
      * 對象的解構(gòu)賦值,右邊的以字段(變量名與變量值)形式存在,與左邊變量名的順序無關(guān); 左邊的變量與右邊的變量一直,不可缺少
          var { foo, bar } = { foo: "aaa", bar: "bbb" };
          foo // "aaa"
          bar // "bbb"
          var { baz } = { foo: "aaa", bar: "bbb" };
          baz // undefined
  • 模式匹配
  “模式匹配”,只要等號兩邊的模式相同,左邊的變量就會被賦予對應(yīng)的值。
    var [a,b,c]=[1,2,3]; //模式匹配法_變量的批量賦值
    console.log(b);
    //嵌套數(shù)組解構(gòu)
    let [foo,[[fa],fb],fc] = [1,[[2],3],4];
    console.log(fa)
    let [one,,three] = [1,2,"123"];
    console.log(three)
    let [start, ...d]=["999",2,"56","00"];
    console.log(start)
    let [x, y, ...z] = ['a'];
    console.log(x)
    console.log(y) 
    console.log(z)
    let [...arr] = [];
    console.log(arr) //數(shù)組
    如果解構(gòu)不成功,變量的值就等于undefined
    var [fo] = [];  // fo undefined
    var [bar, fo] = [1]; // fo undefined
    // 如果右邊不是數(shù)組,或者嚴(yán)格地說,不是可遍歷的結(jié)構(gòu),那么會報(bào)錯(cuò):
    let [foo] = 1;
    let [foo] = false;
    let [foo] = NaN;
    let [foo] = undefined;
    let [foo] = null;
    let [foo] = {};

ES5與ES6區(qū)別

  • 變量聲明方式
  ES5:2種方式。var, function
  ES6:6種方式。var, function,let, const, import, class
  • 默認(rèn)值
    ES6允許變量指定默認(rèn)值。
    var [foo = true] = [];
    foo // true
    [x, y = 'b'] = ['a']; // x='a', y='b'
    [x, y = 'b'] = ['a', undefined]; // x='a', y='b'
    ES6內(nèi)部使用嚴(yán)格相等運(yùn)算符(===),判斷一個(gè)位置是否有值。所以,如果一個(gè)數(shù)組成員不嚴(yán)格等于undefined,默認(rèn)值是不會生效的
    var [x = 1] = [undefined];
    x // 1
    var [x = 1] = [null];
    x // null
  上面代碼中,如果一個(gè)數(shù)組成員是null,默認(rèn)值就不會生效,因?yàn)閚ull不嚴(yán)格等于undefined
  惰性求值: 如果默認(rèn)值是一個(gè)表達(dá)式,那么這個(gè)表達(dá)式是惰性求值的,即只有在用到的時(shí)候,才會求值
  默認(rèn)值可以引用解構(gòu)賦值的其他變量,但是該變量必須已經(jīng)聲明,否則會報(bào)錯(cuò)。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • let 和 const 命令 let 命令 塊級作用域 const 命令 頂層對象的屬性 gl...
    安小明閱讀 1,041評論 0 0
  • let 命令 塊級作用域 const 命令 頂層對象的屬性 global 對象 let 命令 基本用法 ES6 新...
    嘉奇呦_nice閱讀 1,695評論 0 2
  • 你可能已經(jīng)聽說過ECMAScript 6(簡稱 ES6)了。ES6 是 Javascript 的下一個(gè)版本,它有很...
    奮斗的小廢魚閱讀 807評論 0 16
  • 《ECMAScript6 入門》阮一峰 讀書筆記 let和constlet聲明的變量僅在塊級作用域內(nèi)有效,var聲...
    親愛的孟良閱讀 808評論 1 2
  • 不知不覺間,你已經(jīng)到了而立之年。 兩年前,我以一名學(xué)生的身份來到你的世界里。曾幻想過會在你這會遇到什么樣的人,發(fā)生...
    小時(shí)公子閱讀 597評論 13 9

友情鏈接更多精彩內(nèi)容