標籤:make color 表達 缺陷 形參 分享 second 獲得 分離
ES6之前函數形參的預設值設定
當前一個運算元值為false時,總會返回後一個值。對於函數的具名引數,前一個運算元的值為false時,
總會返回後一個值,對於函數的具名引數,如果不顯示傳值,則其值預設為undefined,但是這個方法有缺陷
當我們為timeout傳入0時,即使這個值為合法的,boolean判斷仍為false
在這種情況下,更安全的是使用typeof
ES6 函數參數預設值
在這個函數中,只有第一個參數被認為是總要為其傳入值的,其他兩個參數都有預設值,而且不需要添加任何校正值是否缺失的代碼
makeRequest("/foo") // 使用參數timeout和callback的預設值
makeRequest("/foo", 500); // 使用參數callback的預設值
makeRequest("/foo", 500, function(body){doSomething(body)}); // 不使用預設值
按照ES6寫法,url是必需參數,聲明函數時,可以為任意參數指定預設值,在已指定預設值的參數後可以繼續聲明無預設值參數,例如:
在這種情況下,只有當不為第二個參數傳入值或主動為第二個參數傳入undefined時才會使用timeout的預設值,
makeRequest("/foo", undefined, function(body){doSomething(body);}); // 使用timeout預設值
makeRequest("/foo"); // 使用timeout預設值
makeRequest("/foo", null, function(body){doSomething(body);}); // 不使用timeout預設值
對於預設參數值,null也是一個合法值
預設參數值對arguments對象的影響
(1)ES5 非strict 模式下
在非strict 模式下,具名引數的變化會同步更新到arguments對象中
(2)ES5 strict 模式下
無論具名引數如何變化,arguments對象將不再隨之改變,始終等於調用函數時傳入的參數值(即["a", "b"])
(3)ES6 中
ES6 中,如果一個函數使用了預設參數值,則無論是否顯示定義了strict 模式,arguments對象的行為都將和ES5 strict 模式下一致。
預設參數值的存在使得arguments對象保持與具名引數分離
只給函數傳遞一個參數在,則arguments[0] 值為 "a",arguments[1] 值為undefined,arguments.length為1;改變first 和second 不會影響arguments。
所以總是可以通過arguments對象將參數恢複為初始值
預設參數運算式
在上述代碼中,如果不傳入最後一個參數,就會調用getValue()函數來得到正確的預設值
注意:初次解析函數不會調用getValue()方法,當調用add()方法且不傳入第二個參數時才會調用
當使用函數調用結果作為預設值時,如果忘記寫小括弧,傳入的將是對函數的引用,而不是函數調用結果
因為預設參數是在函數調用時求值,所以可以使用先定義的參數作為後定義參數的預設值
還可以將first的值傳入一個函數來獲得second的值
在引用參數預設值的時候,只允許引用前面參數的值,即先定義的參數不能訪問後定義的參數。
預設參數的臨時死區
回顧上述例子,當調用add(1,1)時,相當於執行以下代碼:
let first = 1;
let second = 1;
調用add(1)時,
let first = 1;
let second = getValue(first); // first 已經從臨時死區中解放出來了
上述代碼:
調用add(1,1)時,
let first = 1;
let second = 1;
調用add(1)時,
let first = second; // 出錯,因為此時second還處於臨時死區中
let second = 1;
函數參數有自己的範圍和臨時死區,和函數體的範圍是獨立的,就是說函數參數預設值不能訪問函數體內聲明的變數
函數形參的預設值