跳到主要內容
黯羽輕揚每天積累一點點

預設參數和不定參數_ES6 筆記 4

免費2016-04-17#JS#ES6默认参数#ES6不定参数#JS可变参函数#JS设置默认参数

預設參數和不定參數一直通過某些技巧來實現,現在終於「合法」了

##一。作用

預設參數和不定參數的目標是完全取代 arguments 物件

嚴格模式('use strict';)對 arguments 做了一些限制,如下:

  • eval 和 arguments 不能通過程式語法被綁定 (be bound) 或賦值

  • 參數的值不會隨 arguments 物件的值的改變而變化,反之亦然

  • 不再支援 arguments.callee

(摘自 嚴格模式 - JavaScript | MDN

前兩條都是對 arguments 物件的不滿,但因為 arguments 物件是實現可變參函式的關鍵方法(當然,也可以用 Object/Array 型別參數模擬,但不如 arguments 方便靈活),還得繼續支援,所以希望通過嚴格模式(補丁)來限制 arguments 物件

而第三條表示黑科技被封印了,arguments 現在名副其實了(只和參數打交道)

ES6(新版本)在嚴格模式的基礎上更進一步,希望大家慢慢忘掉 arguments 物件,而不定參數就是替代方案,還有錦上添花的預設參數

##二。不定參數

...arg 語法帶來了更好的語義(表示不定參數)

不定參數提供了可變參函式(可以接受任意多個參數的函式)的另一種實現方式(不需要 arguments 物件),特點如下:

  • 可讀性更好,從參數列表就可以看出該函式是可變參函式,而且解決了參數索引(arguments[0])的問題

  • 不定參數必須在參數列表末尾,沒有額外參數時值為 [],而不是 undefined

例如:

function containsAny(s, ...aSubStr) {
    for (var subStr of aSubStr) {
        if (s.indexOf(subStr) !== -1) {
            return true;
        }
    }

    return false;
}
// test
console.log(containsAny('ECMAScript 6', 'es'));         // false
console.log(containsAny('ECMAScript 6', 'es', '6'));    // true

不定參數帶來的便利是參數操作更容易了,不再需要這樣的步驟:

var fn = function(a, b) {
    var args = Array.prototype.slice.call(arguments);
    // 切掉命名參數 a 和 b
    var others = args.slice(2);
    // ...
}

##三。預設參數

arg=defaultVal 語法表示預設參數,與其它語言一樣。特點如下:

  • defaultVal 可以是任意合法表示式,所以可以根據左邊的參數生成當前參數的預設值

  • undefined 相當於佔位符,仍然使用預設值,而不是傳入的 undefined

  • 標準規定在使用不定參數或預設參數的函式中禁止使用 arguments 物件,但 Chrome49,FF45 和 thinkjs 都沒有實現此限制

例如:

function error(type = 'Undefined') {
    console.log(`${type} error occurs`);
}
// test
error();            // Undefined error occurs
error('Script');    // Script error occurs

// 動態生成預設值與傳入 undefined
function hoho(name, sex, words = sex === 'F' ? 'Hi Girl' : 'Hello boy') {
    console.log(`${words}, you are ${name}`);
}
hoho('Sam', 'M');   // Hello boy, you are Sam
hoho('Lis', 'F');   // Hi Girl, you are Lis
hoho('Mee', 'F', undefined);    // Hi Girl, you are Mee

// arguments 物件
function fun(arg = 'defaultVal', ...aOther) {
    var args = Array.prototype.slice.call(arguments);
    console.log(args.length);
}
fun(1, 2, 3);   // 3

算是錦上添花的小東西,避免了以前需要藉助註釋繁瑣寫法:

/**
 * [fn description]
 * @param  {[type]}   a [description]
 * @param  {[type]}   b 可選,預設值為{},表示 xxx
 * @return {Function}   [description]
 */
var fn = function(a, b) {
    b = b || {};    // 設定 b 的預設值為{}
}

這種老方法既麻煩又容易出錯(b 可以為 0 或者 false 時更麻煩),有了預設參數就不需要多餘的註釋了,除非預設值生成方式很複雜,需通過註釋額外說明

##四。總結

本篇內容非常少,主要是程式碼可讀性上的提升,2 點:

  • 設定預設參數更方便了,語法就是預設語法

  • 可變參函式有了更合理的實現方法,不再依賴 arguments 物件了

###參考資料

  • 《ES6 in Depth》:InfoQ 中文站提供的免費電子書

評論

暫無評論,快來發表你的看法吧

提交評論