讀書筆記:深入理解ES6 (三)

第三章 函數

這一章主要介紹了在ES6規範中,對於函數這一塊知識進行的一些修訂和改進,主要目的就是讓使用JavaScript編程可以更少出錯,同時也更加靈活。

 

第1節. 函數形參的默認值

  1.1 在ES5中,在函數體內要對形參的值進行進一步的判斷,如果不滿足條件,則給其一個默認值。例如:

function makeRequest(url, timeout, callback) 
{
    timeout = timeout || 2000;
    
    //other code          
}

 

    而在ES6中,爲了更加簡化函數體的代碼,給形參賦默認值的操作可以直接在寫參數的時候加上,以此減少函數體內的代碼量。例如:

 

function makeRequest(url, timeout = 2000, callback)
{
        //other code
}      

   

   1.2 默認參數值對 arguments 對象的影響。

    在ES5非嚴格模式下,函數命名參數的變化會體現在 arguments 對象中。即,參數值改變後,arguments 對象中原來存儲的值會同時發生改變;而在ES5嚴格模式和ES6中,參數值改變後,arguments 對象中的值不會改變,仍舊是原來的值。

 

第2節 處理無命名參數

  2.1 無命名參數,即沒有顯式聲明的參數。在ES5中,可以使用 arguments  對象來表示和進行相應操作。

  2.2 在ES6中,可以使用三個點 (...) 加上一個參數名來表示不定參數。例如:

function pick( object, ...keys )
{
    // other code   
}

  注意:不定參數在使用的時候有兩個限制:

        1)每個函數只能聲明一個,且只能放在參數的末尾;

      2)不定參數不能用於對象字面量 setter 之中。

 

第3節 增強的Function構造函數

  在ES5中,可以像下面這樣使用構造函數:

var add = new Function( "first", "second", "return first + second" );

console.log( add(1, 1) ); // 2

  在ES6中,Function構造函數可以使用默認參數和不定參數。例如:

var add = new Function("first", "second=first", "return first + second");

console.log( add(1, 1) ); //2
console.log( add(1) ); //2

var pickFirst = new Function( "...args", "return args[0]" );

console.log( pickFirst(1, 2) ); // 1

 

第4節 展開運算符

  4.1 什麼是展開運算符?

  使用三個點 (...) 加上一個數組的名字,例如下面的 "...values" :

let values = [25, 50, 75, 100];
...values // 這個就是展開運算符

  4.2 展開運算符的好處是什麼?

  好處就是可以讓數組的元素可以作爲單個的字符來使用。例如:

  Math.max()方法中,只能傳入字符串作爲參數,但是如果想傳入一個數組,然後找到這個數組的最大值,這個時候怎麼辦呢?這個時候可以使用展開運算符。如下:

let values = [25, 50, 75, 100];
Math.max( ...values );

 

第5節 name屬性

  5.1 JavaScript中,有多種定義函數的方式。例如:正常定義的函數、函數表達式、匿名函數等。爲了便於調試函數,於是在ES6中,添加了函數的 name 屬性。該屬性的值可以返回當前的函數名。

  5.2 當然也有一些特殊的情況,會在函數名的前面加上一些字符串前綴。例如:

    getter函數,函數名前面會有get

    setter函數,函數名前面會有set

    bind()函數,函數名前面會有bound

  5.3 注意,函數name屬性不一定和原函數名完全相同,所以它只是一個調試的輔助信息,而不能用它來獲取對函數的引用。

 

第6節 明確函數的多種用途

  6.1 JavaScript函數有兩個不同的內部方法:[[ Call ]] 、 [[ Construct ]]。

    當通過 new 關鍵字調用函數的時候,執行的是 [[ Construct ]] 函數。如果不是通過 new 關鍵字來調用函數,那麼執行的就是 [[ Call ]] 函數。

  6.2 不是所有函數都有 [[ Construct ]]方法。

    例如ES6中的箭頭函數就沒有這個[[ Condtruct ]]方法。

  6.3 在ES6中,可以通過 new.target 這個屬性來判斷是否是通過 new 關鍵字調用的函數。

 

第7節 塊級函數

  7.1 先拋出4個概念:

    ES5 非嚴格模式、ES5嚴格模式; ES6 非嚴格模式、ES6 嚴格模式。

  7.2 塊級函數是什麼?

    塊級函數即在代碼塊中聲明的一個函數。例如:

"use strict"

if (true)
{
    //在ES5中拋出語法錯誤,在ES6中不報錯
    function doSomething()
    {
         // 空函數
     }      
}

 

  7.3 在ES5嚴格模式中,此種聲明會報錯。

    在ES6中,此種聲明式合法的,不會報錯。但是有一個小小的區別:

      ~在ES6 嚴格模式中,塊級函數會被提升至代碼塊頂部,用完即銷燬;

      ~在ES6 非嚴格模式中,塊級函數會被提升至外圍函數或者全局作用域的頂部。

 

第8節 箭頭函數

  8.1 定義:

    箭頭函數是使用箭頭 ( => ) 定義的函數。

  8.2 與傳統函數的區別:

  • 沒有this /  super / arguments / new.target 綁定
  • 不能通過 new 關鍵字調用    
  • 沒有原型(Prototype)
  • 不可以改變 this 的綁定
  • 不支持 arguments 對象
  • 不支持重複的命名參數

  8.3 箭頭函數與this。

    如果箭頭函數被非箭頭函數包裹,則 this 綁定的是最近一層非箭頭函數的 this 。否則 this 的值會被設置爲全局對象。

  8.4 使用場景。

    所有使用匿名函數的地方都適合使用箭頭函數來改寫。同時,箭頭函數也適合數組處理。

 

第9節 尾調用優化

  9.1 什麼是尾調用?

    當一個函數作爲另一個函數的最後一條語句被調用時,就叫做尾調用。例如:

function doSomething()
{
   return doSomethingElse(); //尾調用 
}

  9.2 使用場景:

    當寫遞歸函數的時候,可以使用這一特性。除非你嘗試優化一個函數,否則無須思考此類問題。

 

(本節完)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章