第三章 函數
這一章主要介紹了在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 使用場景:
當寫遞歸函數的時候,可以使用這一特性。除非你嘗試優化一個函數,否則無須思考此類問題。
(本節完)