天天看點

ES6 函數參數預設值 default

參數預設值

基本用法

ES6允許為函數參數設定預設值,即直接寫在參數定義後面。

function log(x, y = 'world') {
    console.log(x, y);
}

log('Hello');   // Hello world
log('Hello', 'China');  // Hello China
log('Hello', '');   // Hello 
           

ES6的寫法非常簡潔自然,如下例子:

function Point(x = 0, y = 0) {
    this.x = x;
    this.y = y;
}

var p = new Point();
p // {x:0, y:0}
           

除了簡潔,ES6的寫法還有兩個好處:

- 閱讀代碼的人,可以立刻意識到哪些參數是可以省略的,不用檢視函數體或文檔;

- 有利于将來代碼的優化,即使未來的版本在對外接口中,徹底去掉這個參數,也不會導緻以前的代碼無法運作。

參數變量是預設聲明的,是以不能用

let

const

再次聲明。

function foo(x = 0) {
    let x = ; // error
    const x = ; // error
}
           

上面代碼中,參數變量

x

是預設聲明的,在函數體中,不能用

let

const

再次聲明,否則會報錯。

與解構指派預設值結合使用

函數參數預設值是可以與解構指派(destructuring)的預設值,結合起來使用。

function foo({x, y = }) {
    console.log(x, y);
}

foo({});    // undefined 1
foo({x: });    // 1 1
foo({x:, y: });   // 1 2
foo();  // TypeError: Cannot match against 'undefined' or 'null'.
           

上面代碼使用了對象的解構指派預設值,隻有當函數

foo

的參數是一個對象時,變量

x

y

才會通過解構指派生成,如果函數

foo

調用時參數不是對象,就無法進行解構指派,進而報錯。

參數預設值的位置

通常情況下,定義了預設值的參數,應該是函數的尾參數。因為這樣比較容易看出來,到底省略了哪些參數。如果非尾參數設定預設值,其實這個參數是沒法省略的。

function f(x = , y) {
    return [x, y];
}

f();    // [1, undefined]
f();   // [1, undefined]
f(,);  // [1, 1]
f(undefined, );    // [1, 1]

function func(x, y = , z) {
    return [x, y, z];
}

func();    // [undefined, 1, undefined]
func();    // [1, 1, undefined]
func(, ,);    // 報錯
func(, undefined, );  // [1, 1, 2]
           

上面例子中,有預設值的參數都不是尾參數,此時,無法隻省略該參數,而不省略它後面的參數,除非顯示傳入

undefined

函數的

length

屬性

函數指定了預設值後,函數的

length

屬性傳回的就不再是函數參數個數,而是第一個指定預設值的前面參數個數。也就是說指定了預設值後,函數的

length

屬性将失真。

(function(a) {}).length // 1
(function(a = 1) {}).length // 0
(function(a, b, c = 1, d) {}).length   // 2
(function(...args) {}).length   // 0
           

這是因為

length

屬性的含義是,該函數預期傳入的參數個數,某個參數指定預設值後,預期傳入的參數個數就不包括這個參數及其後面的參數。同時,Rest參數也不會計入

length

屬性。

作用域

一個需要注意的地方,如果參數預設值是一個變量,則該變量所處的作用域與其它變量的作用域一樣,即先是目前函數的作用域,然後才是全局作用域。

應用

利用參數預設值,可以指定某個參數不得省略,如果省略則抛出一個錯誤。

function throwIfMissing() {
    throw new Error("Missing parameter");
}

function foo(mustBeGiven = throwIfMissing()) {
    return mustBeGiven;
}

foo(); // Error: Missing parameter
           

上面代碼中

foo

函數,如果調用的時候沒有給出參數,則會調用預設值

throwIfMissing

函數,進而抛出一個錯誤。

此外,還可以将參數預設值設為

undefined

,表明這個參數是可以省略的。

function foo(optional = undefined) { ... }
           

繼續閱讀