es6學習筆記

《ECMAScript6 入門》阮一峰 讀書筆記

  • let和const
    • let
      1. 聲明的變量僅在塊級作用域內有效,var聲明的變量在全局范圍內有效
      2. let不存在變量提升,所以變量一定要先聲明后使用,換言之,var是有變量提升的(也就是可以先使用后聲明,聲明在編譯的時候會被提升到最開頭)
      3. 暫時性死區,也就是使用let命令聲明變量之前,該變量都是不可用的,也就是第二條。暫時性死區的本質就是,只要一進入當前作用域,所要使用的變量就已經存在了,但是不可獲取,只有等到聲明變量的那一行代碼出現,才可以獲取和使用該變量。
      4. 不允許重復聲明,也就是在同一個作用域內不能重復聲明同一個變量。
  • 塊級作用域
    1. 不合理場景一
var tmp = new Date();
function f() {
  console.log(tmp);
  if (false) {
      var tmp = "hello world";
  }
}
f(); // undefined,因為變量提升內層的tmp變量覆蓋了外層的tmp變量????
??有疑惑,并不理解。。。
2. 不合理場景二,變量泄漏為全局變量(比如for循環里面的計數變量,如果用var來聲明,其實在全局也是可以訪問到的)
3. 塊級作用域與函數聲明
    - es5規定函數只能在頂層作用域和函數作用域之中聲明,不能在塊級作用域中聲明,比如在if語句里面就不能聲明一個變量,但實際上,瀏覽器是支持的
    - es6明確允許在塊級作用域之中聲明函數。比較特別的是,塊級作用域之中,函數聲明語句的行為類似于`let`,在`塊級作用域之外是不可以引用的`
    
    ```
    eg:
    function f(){console.log("I am outside");}
    (function (){
        if(false){
          function f(){console.log("I am inside");}
        }
        f()
    }())
    *===================================================*
    es5中實際上是如此運行的:
    function f(){console.log("I am outside");}
    (function (){
        function f(){console.log("I am inside");}//變量提升
        if(false){}
        f()
    }())
    *===================================================*
    es6中實際運行代碼如下:
    function f(){console.log("I am outside");}
    (function(){
    f()//在塊級內聲明的那個inside的f函數對作用域之外沒有影響,所以相當于不存在,
    調用的是外面的函數,因為作用域查找都是向外查找噠!
    }())
    ```
    
    - ??為了兼容的問題,es6允許瀏覽器可以不遵守上面的規定,也就是可以有自己的行為方式,具體表現為(也就是實際上定義函數的時候遵守的規則,只針對支持es6的瀏覽器有效):
        - 允許在塊級作用域內聲明函數
        - 函數聲明類似于var,即會提升到全局作用域或函數作用域的頭部
        - 同時,函數聲明還會提升到所在的塊級作用域的頭部
     - 在塊級作用域內聲明函數的時候,塊級作用域一定要加大括號,比如在if里面聲明一個函數,if后面一定要有大括號
  • const聲明一個只讀的常量,聲明之后,值不能改變。所以,聲明的時候就要賦值,其他的和let一樣。有一個注意的點是,比如const了一個數組,這個數組本身是不能給賦值的,但是這個數組是可以push一個變量的!

  • 頂層對象的屬性

    • 全局變量在es5中是頂層對象的屬性,es6規定,var和function命令聲明的全局變量依然是頂層對象的屬性,但是let、const、class命令聲明的全局變量不屬于頂層對象的屬性。
  • 頂層對象

    混亂的頂層對象

    • 瀏覽器里面,頂層對象是window,但Node和Web Worker沒有window
    • 瀏覽器和Web Worker里面,self指向頂層對象,但是Node 沒有self
    • Node里面,頂層對象是global,但其他環境都不支持

    為了在不同的環境中都能去到頂層對象,一般使用this變量,但是有局限性
    - 全局環境中,this會返回頂層對象,但是,Node模塊和ES模塊中,this返回的是當前模塊
    - 函數里面的this,如果函數不是作為對象的方法運行,而是單純作為函數運行,this會指向頂層對象,但是,嚴格模式下,this會返回undefined
    - 不管是嚴格模式,還是普通模式,new Function('return this')(),總是會返回全局對象,但是,如果瀏覽器用了CSP(Content Security Policy,內容安全政策),那么evalnew 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('unalble to locate global object'); }

  • 變量的解構賦值

es6允許按照一定模式,從數組和對象中提取值,對變量進行復賦值,成為解構賦值。

  • 數組的解構賦值
    • “模式匹配”,也就是只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值。
    let [foo, , baz] = [1,2,[d]];//foo就是1,baz就是[d]這個數組
    let [head, ...tail] = [1,2,3,4];//head就是1,tail就是[2,3,4]
    let [x,y,...z] = ['a'];//x就是“   a”,y是undefined(解構不成功的話,變量的值就等于undefined),z是[],為啥z是[](????為啥??),因為"..."是將右邊剩余的值用數組的形式賦給左邊的值,所以z就得到了一個空的數組
    let [a,[b],d] = [1,[2,3],4];//a是1,b是2(完全對應過去,如果b不加外面的中括號,那b就是[2,3]),d是4
    
    • 等號的右邊如果不是可遍歷的結構,會報錯的
    • 默認值,允許指定默認值,數組成員嚴格等于undefined才會使默認值生效
    var [foo = true] = [];//foo是true
    
  • 對象的解構賦值
    • 變量必須與對象的屬性同名,才能取到正確的值,如果沒有對應的同名屬性,取不到值的話,值為undefined
    var {bar, foo} = {foo:'aaa',bar:'bbb'}//foo的值是'aaa',bar的值是'bbb'
    //注意真正被賦值的是誰
    var {foo:baz} = {foo:"aaa",bar:"bbb"}//baz的值是"aaa"而不是foo的值是“aaa”,foo是個“模式”
    
    誰后面有“:”,誰就是模式,并不是變量
    • 這種寫法,變量的聲明和賦值是一體的,像下面,如果用let或const是不行的,但是用var是可以的。
    let foo;
    let {foo} = {foo:1}//這樣會報錯滴,因為foo在上面已經聲明過了,所以不能再次聲明
    //如果非常想用let并且分開的話,可以用下面的方式
    let foo;
    ({foo} = {foo:1})//這樣不會報錯,外面必須用()包起來,因為解析器會將起首的大括號理解成一個代碼塊而不是賦值語句。
    
    • 默認值,默認值生效的條件是,對象的屬性值嚴格等于undefined,同樣,如果解構失敗(也就是對應右邊沒有相同變量名的屬性),那么變量的值等于undefined
    • 實際應用場景:可以很方便的把一些對象的屬性值賦值給其他的變量,不用一個一個的寫
    var { log,sin,cos } = Math
    
  • 字符串的解構賦值
    var [a,b,c] = 'hello';
    //a==>h,b==>e,c==>l
    var {length:len} = 'hello';
    //len的值是5,有點懵???(類似數組的對象都有一個length屬性,所以就5了???)
    
  • 數值和布爾值的解構賦值

    解構賦值時,如果等號右邊是數值或布爾值,則會先轉為對象,(undefined和null無法轉為對象,所以對他們解構賦值會出錯)

  • 函數形式參數的解構賦值
  • 變量的解構賦值的用途
    1. 交換變量的值
    [x,y] = [y,x]//數組的解構是嚴格按照順序的
    
    1. 從函數返回多個值:函數一次只能返回一個值,如果要返回多個值,只能將她們放在數組或對象里返回,有了解構賦值,可以很方便的取出這些值
    function example(){
      return [1,2,3]
    }
    var [a,b,c] = example()//這樣就賦值了,多方便??
    
    1. 函數參數的定義
    function f([x,y,z]){....}
    f([1,2,3])
    
    1. 提取JSON數據
    var jsonData = {
     id:42,
     status:"ok",
     data:[22,3]
    }
    let { id, status, data:number } = jsonData;
    
    1. 遍歷Map結構
    2. 輸入模塊的指定方法

  • 字符串的擴展(這節好深奧,先放下??
    • 字符的Unicode表示法,用\uxxxx形式來表示一個字符,其中xxxx表示字符的碼點
  • 正則的擴展
  • 數值的擴展

  • 數組的拓展

    • Array.from(),用于將兩類對象轉為真正的數組:類似數組的對象和可遍歷的對象。
    let arrayLike = {
      '0':'a',
      '1':'b',
      '2':'c',
      length:3
    };//類似數組的對象
    let arr = Array.from(arrayLike);//['a','b','c']
    
    • 實際應用中,常見的類似數組的對象是DOM操作返回的NodeList集合,以及函數內部的arguments對象。(所謂類似數組的對象本質特征只有一點,即必須有length屬性,任何有length屬性的對象,都可以通過Array.from方法轉為數組)
    • Array.of(),用于將一組值轉換為數組,沒有參數的時候返回一個空數組
    Array.of(1,2,4)//【1,2,4】
    
    • copyWithin(),在當前數組內部,將指定位置的成員復制到其他位置(會覆蓋原有成員),然后返回當前數組,也就是會修改當前數組。
    Array.prototype.copyWith(target,start,end)//接受三個參數,其中target是必需的,target代表從該位置開始替換數據,start表示從該位置開始讀取數據,默認為0,負數則表示倒數,end表示到該位置前停止讀取數據,默認等于數組長度,負數則表示倒數
    [1,2,3,4].copyWithin(0,3)//[4,4,4,4],從0開始用3位置上(也就是4這個數字到末尾的0來替換0
    
    • 數組實例的find()和findIndex()

    find方法用于找出第一個符合條件的數組成員,參數是一個回調函數,所有數組成員依次執行該回調函數,直到找出第一個返回值為true的成員,然后返回該成員。如果沒有符合條件的成員,則返回undefined。回調函數可以接受三個參數,依次為當前的值,當前的位置,原數組

    [1,2,-5].find(n => n < 0)//返回第一個小于0的成員
    

    findIndex方法返回第一個符合條件的數組成員的位置,如果都不符合條件,則返回-1,回調函數參數和find方法一致。

    find和findIndex方法都可以接受除回調函數以外的第二個參數,用來綁定回調函數的this對象。
    
    • 數組實例的fill()

    fill方法使用給定值,填充一個數組。如果數組中已有元素,則會全部被抹去。參數和copyWithin函數的參數是一致的。

    ['a','b','c'].fill(7)//返回一個[7,7,7]
    
    • 數組實例的entries(),keys()和values()----遍歷數組的函數
    ------對鍵名的遍歷
    for(let index of ['a','b'].keys()){
         console.log(index);
     }//結果如下
     //0
     //1
    ------對鍵值的遍歷
     for(let elem of ['a','b'].values()){
         console.log(elem);
     }//結果如下
     //'a'
     //'b'
     ------對鍵值對的遍歷
     for(let [index,elem] of ['a','b'].entries()){
         console.log(index,elem);
     }//結果如下
     //0 "a"
     //1 "b"
    
    • 數組實例的includes()

    Array.prototype.includes方法返回一個布爾值,表示某個數組是否包含給定的值,與字符串的includes方法類似。

    [1,2,3].includes(2)//包含2,所以返回true
    
    Map結構的has方法,是用來查找鍵名的
    Set結構的has方法,是用來查找值的
    
    • 數組的空位

    數組的空位是指,數組的某一個位置沒有任何值,es6明確的將空位轉為undefined。以上數組的擴展方法都會把空位考慮進去,而不是忽略。

  • 函數的擴展

    • 函數參數的默認值
    function log(x, y = 'world'){
    ...}
    
    • 與解構賦值默認值結合使用(沒看懂??
    • 參數默認值的位置

    非尾部的參數如果設置了默認值,那么這個參數是不能夠省略的!

    • 函數的length屬性

    指定了默認值以后,函數的length屬性,將返回沒有指定默認值的參數個數,也就是說,指定了默認值以后,length屬性將失真。失真也就是不算它

    (function (a,b=2){}).length
    //1
    
    • 作用域---大爺

      1. 如果參數默認值是一個變量,則該變量所處的作用域,與其他變量的作用域規則是一樣的,即先是當前函數的作用域,然后才是全局作用域。
      情況一:
      var x = 1;
      function f(x, y = x){
      略
      }
      //比如這里,y的默認值就是一個變量x,那么x的值要優先取傳進來的x的值,如果沒有,
      才是全局變量中的x。
      
      情況二:
      let x = 1;
      function f(y=x){
        let x = 2;
        console.log(y);
      }
      f()//輸出的是1,因為給y賦值的時候,x尚未在函數內部生成,故取全局變量中的x給y賦值,
      如果此時全局變量中的x不存在,就會報錯了。
      
      情況三:
      let foo = "outer";
      function bar(func = x=> foo){
         let foo = "inner";
         console.log(func());
      }
      bar()
      //當函數的參數是一個函數的時候,該函數的作用域是其聲明時所在的作用域。
      ????bar方法的參數func是一個匿名函數,具體的意義是傳進去x,返回值為foo,
      也就是func()的值,匿名函數聲明的時候(也就是給func賦值的時候),bar函數的作
      用域還沒有形成,所以匿名函數里面的foo指向外層作用域來的foo,輸出的是outer
      ????
      

      2.rest參數

      rest參數形式為"...變量名",用于獲取函數的多余參數,這樣就不需要使用arguments對象了,rest參數搭配的變量是一個數組,該變量將多余的參數放入數組中。??需要注意的是rest參數之后不能再有其他參數,也就是這個參數只能放在最后面。

      function add(...values){
       let sum = 0;
       for(var val of values){
          sum+=val;
       }
       return sum;
      }
      add(2,4,5)//神似python里的參數??
      

    3.擴展運算符

    擴展運算符(spread)是三個點...,rest參數的逆運算,將一個數組轉為用逗號分隔的參數序列。注意,擴展運算符針對的是數組數組數組??也就是把一個數組相當于給拆開了。

    console.log(...[1,2,3])
    //1 2 3
    
    function push(array, ...items){
      array.push(...items);
    }
    function add(x, y){
       return x + y;
     }
     var numbers = [4,3];
     add(...numbers)//7
    
    • 替代數組的apply方法(??總結一下apply方法,因為得知道apply究竟是干嘛才知道怎么個替代法??10.26)

    • 擴展運算符的應用:

      • 合并數組
      var arr1 = ['a','b'];
      var arr2 = ['c','d'];
      var arr = [...arr1,...arr2]
      
      • 與解構賦值結合
      這里和前面的解構賦值很容易混啊??
      const [first,...rest]=[1,2,3,4];
      first===》1
      rest====》2,3,4
      //有個易錯點,和前面很像,就是i 這個...變量只能放在最后??
      
      • 函數的返回值,返回多個值的時候
      • 字符串,可以將字符串轉換為真正的數組
      [...'hello']
      //['h','e','l','l','o']
      
      • 實現了Iterator接口的對象,任何Iterator接口的對象,都可以用擴展運算符轉為真正的數組。
      let arrayLike = {
       '0':'a',
       '1':'b',
       '2':'c',
       length:3
      };
      let arr = [...arrayLike]//TypeError
      //arrayLike是一個類似數組的對象,但是沒有部署Iterator接口,擴展運算符就會報錯,
      這時,可以改為使用Array.from方法將arrayLike轉為真正的數組。
      
      • Map結構和Set結構,Generator函數

      擴展運算符內部調用的是數據結構的Iterator接口,因此只要具有Iterator接口的對象,都可以使用擴展運算符。

    4.嚴格模式use strict

    es6規定,只要函數的形參使用了默認值、解構賦值或者擴展運算符,那么函數內部就不能顯示的設定為嚴格模式。

    5.name屬性,函數的name屬性,返回該函數的函數名

    6.箭頭函數 =>

    • 如果箭頭函數不需要參數或者需要多個參數,就使用一個圓括號代表參數部分。
    • 如果箭頭函數的代碼塊部分多于一條語句,就要使用大括號將他們括起來,并且使用return語句返回
    • 如果要返回一個對象,外面要用小括號包起來,因為大括號被解釋為代碼塊,所以必須在對象外面加上括號
    • 函數體內的this對象,就是定義時所在的對象,而不是使用時所在的對象,在箭頭函數中,this是固定的。因為箭頭函數沒有自己的this,他們的this其實都是外層對象(也就是函數)的this。所以bind(),call(),apply()這些方法無法改變this的指向。
    • 不可以當做構造函數,也就是不能用new操作符
    • 不可以使用arguments對象,該對象在函數體內不存在,如果要用,可以用rest參數代替
    • 不可以使用yield命令,因此箭頭函數不能用做generator函數

    7.綁定this::es7的一個題案,如果用的話需要babel轉碼器

    雙冒號左邊是一個對象,右邊是一個函數,該運算符會自動將左邊的對象,作為上下文環境(即this對象)綁定到右邊的函數上面,如果雙冒號左邊為空,右邊是一個對象的方法,則等于將該方法綁定在該對象上面。

    8.尾調用優化??看不懂??10.27

    尾調用是函數式編程的一個重要概念,指的是某個函數的最后一步是調用另一個函數

  • 對象的擴展

    • 屬性的簡潔表示法
    情況一:
    var foo = 'a';
    var baz = {foo};
    //以往寫對象的時候要屬性名、屬性值成對出現,es6允許在對象中,只寫屬性名,
    不寫屬性值,這時,屬性值等于屬性名所代表的變量。
    情況二:
    var o = {
      method(){
          return "hello";//這不就是之前寫react的用法嘛??
      }
    };
    等同于:
    var o = {
      method:function(){
          return "hello";
      }
    };
    綜合的例子:
    var birth = '2000/01/01';
    var Person = {
    name: '張三',
    //等同于birth: birth
    birth,//react返回對象的時候就是這樣寫的!!!??
    // 等同于hello: function ()...
    hello() { console.log('我的名字是', this.name); }
    };
    
    • 屬性名表達式??
    • Object.js()

    比較兩個值是否相等,只有兩個運算符:相等運算符==和嚴格相等運算符===,前者會自動轉換數據類型,后者的NaN不等于自身,以及+0等于-0。Object.is用來比較兩個值是否嚴格相等,彌補了===的缺點。

    • Object.assign()

    Object.assign()用于對象的合并,將源對象的所有可枚舉屬性,復制到目標對象。

    Object.assign(target,source1,source2...)
    //第一個參數是目標對象,也就是最終的,后面都是源對象。如果只有一個參數那就直接返回
    //????????如果目標對象與源對象有同名屬性,或者多個源對象有同名屬性,則后面的屬性會
    覆蓋前面的屬性
    ??undefined和null不能放在目標對象的位置(放,報錯,不放也就是放在別的位置會被跳過)
    ??字符串可以作為源對象,復制到目標對象里會是數組的形式,布爾值和數值都不能作為源對象,
    雖然不報錯,但是會跳過
    
    ??注意點
    1.Object.assign是淺拷貝,如果源對象某個屬性的值是對象,如果源對象某個屬性的值是對象,
    那么目標對象拷貝得到的是這個對象的引用。
    2.Object.assign也可以處理數組,但是也是將數組視為對象。
    
    - Object.assign常見用途
      - 為對象添加屬性
      - 為對象添加方法,目標對象就是xxx.prototype,然后源對象就是用大括號包裹的函數
      - 克隆對象
      - 合并多個對象
      - 為屬性指定默認值(可以將屬性的默認值為一個對象,用戶輸入的為另一個對象,兩個對象作為源對象復制給目標對象,因為用戶輸入的放在后面所以會覆蓋掉默認值對象的值,so~)
    
    • 屬性的可枚舉性

    對象的每個屬性都有一個描述對象(Descriptor),用來控制該屬性的行為。Object.getOwnPropertyDescriptor方法可以獲取該屬性的描述對象

    let obj = {foo:123};
    Object.getOwnPropertyDescriptor(obj,'foo')
    //{
    //    value:123,
    //    writable:true,
    //    enumerable:true,是否可以枚舉
    //    configurable:true
    //}
    
    • 屬性的遍歷
      1. for...in,遍歷對象自身的和繼承的可枚舉屬性(不包含Symbol屬性)
      2. Object.keys(obj),返回一個數組,包括對象自身的(不含繼承的)所有可枚舉屬性(不含Symbol屬性)。
      3. Object.getOwnPropertyNames(obj),返回一個數組,包含對象自身的所有屬性(不含Symbol屬性,但是包括不可枚舉屬性)。
      4. Object.getOwnPropertySymbols(obj),返回一個數組,包含對象自身的所有Symbol屬性
      5. Reflect.ownKeys(obj),返回一個數組,包含對象自身的所有屬性,不管是屬性名是Symbol或字符串,也不管是否可以枚舉。
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容

  • 強大的for-of循環 ES6不會破壞你已經寫好的JS代碼。目前看來,成千上萬的Web網站依賴for-in循環,其...
    Awe閱讀 7,525評論 2 7
  • ECMAScript 6.0( 以下簡稱ES6) 是JavaScript語言的下一代標準。 ECMAScript和...
    EarthChen閱讀 457評論 0 0
  • 第一章 塊級作用域綁定 let 和 const 都是不存在提升,聲明的都是塊級標識符都禁止重聲明 每個const聲...
    NowhereToRun閱讀 1,595評論 0 2
  • 一. 函數參數的默認值 ES6 允許為函數的參數設置默認值,即直接寫在參數定義的后面。 Tips:參數變量是默認聲...
    markpapa閱讀 244評論 0 0
  • 終于您今晚現身啦~ 很久沒現身啦。 讓我激動的不自覺的微笑,從心底里開心起來。從店里騎摩拜到宿舍,吹著涼風,這感...
    淡墨o閱讀 396評論 0 0