在 Day28 - 函式 中有提到,可以在函式的小括號內放入參數 (parameters),若有多個參數則以 逗號 ,
做區格,而參數名稱可以自行定義,與傳入的值無關,如以下範例:
在呼叫函式的小括號內放入值,參數會依序接收
function fun(parameter1, parameter2) {
console.log(parameter1, parameter2);
}
fun('參數1', '參數2');
// 參數1 參數2
若傳入的參數的值數量不足,則系統會先給予參數一個 undefined
的值
function fun(parameter1, parameter2, parameter3) {
console.log(parameter1, parameter2, parameter3);
}
fun('參數1', '參數2');
// 參數1 參數2 undefined
若要避免沒有傳入值,可使用 ES6 的語法,使函式參數有其預設值
function fun(parameter1, parameter2, parameter3 = '我是參數預設值') {
console.log(parameter1, parameter2, parameter3);
}
fun('參數1', '參數2');
// 參數1 參數2 我是參數預設值
若帶入參數的值是物件,他們會指向同一個物件參考路徑,所以就算物件變成參數,依然會維持物件傳參考的特性
function fun(obj) {
obj.name = 'Mary';
}
var family = {
name: 'Carol',
};
fun(family);
console.log(family); // {name: 'Mary'}
當 變數 family
賦予一個物件,並作為參數的值傳入,參數 obj
與 變數 family
會指向同一個物件參考路徑,所以當 參數 obj
改變其物件內容,變數 family
也會受到影響
在 Day28 - 函式 有提到,函式陳述式在創造階段時,會先在記憶體中將函式陳述式的所有內容做保留
以下在函式陳述式內放入函式陳述式,並將它與參數的名稱命名為一樣,可以發現 參數 nickName
被 函式 nickName
取代,因此在函式內的函式陳述式一樣會被提升,且不會比傳進的 參數 nickName
更前方,因若為更前方,則答案會是 Carol Carol Mary
function fun(nickName) {
console.log(nickName);
function nickName() {}
console.log(nickName);
nickName = 'Mary';
console.log(nickName);
}
fun('Carol');
// ƒ nickName() {}
// ƒ nickName() {}
// Mary
由此可知,上面例子運作流程如下:
// 1. 創造階段
function fun(nickName) {
console.log(nickName);
function nickName() {}
console.log(nickName);
nickName = 'Mary';
console.log(nickName);
}
// 2. 執行階段
fun('Carol');
參數可以是原始型別,也可以是物件型別,當帶入函式做為參數的值,使此函式成為另一個函式的參數且在另一個函式內調用此函式,稱之為 callback function
function fun(fn) {
fn('Carol');
}
fun(function(nickName) {
console.log(nickName);
});
也可以將呼叫 fun 函式
小括號內的函式另外提出來,如下所示:
function fun1(nickName) {
console.log(nickName);
}
function fun2(fn) {
fn('Carol');
}
fun2(fun1);
上面有提到函式的參數只會提取相對應的數量,而函式引數 (arguments) 則會取得所有傳入的值,並使之成為一個類陣列,而類陣列雖然很像陣列,但無法使用絕大多數的陣列方法
在以下例子中,只用 1 個 參數 a
來接收傳入的值,其餘傳入的值,可利用 arguments
來顯示 (arguments
是專有名稱,不用另外定義)
function fun(a) {
console.log(a, arguments);
}
fun(1, 2, 3, 4);
// Arguments(4) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]
其餘參數 (rest parameter) 是 ES6 的語法,它可以取得不定數量的參數,作用類似於 函式引數 (arguments)
,但其餘參數是陣列,arguments 是類陣列
function fun(a, ...others) {
console.log(a, others);
}
fun(1, 2, 3, 4);
// 1 (3) [2, 3, 4]
需要注意的是其餘參數必須為最後一個參數,且在此參數中只能有一個是其餘參數,否則會出錯
function fun(...others, a) {
console.log(a, others);
}
fun(1, 2, 3, 4);
// 錯誤訊息 - Uncaught SyntaxError: Rest parameter must be last formal parameter
function fun(a, ...others1, b, ...others2) {
console.log(a, others1, others2);
}
fun(1, 2, 3, 4, 5, 6);
// 錯誤訊息 - Uncaught SyntaxError: Rest parameter must be last formal parameter
當宣告一個變數,而此變數已經存在,這個宣告就無任何作用,並不會再變成系統預設值 undefined
var nickName = 'Carol';
var nickName;
console.log(nickName); // Carol
所以,在參數傳遞時,若參數已經定義好值,就算再重複做宣告,不會影響到此參數的值
function fun(nickName) {
console.log(nickName);
var nickName;
console.log(nickName);
nickName = 'Mary';
console.log(nickName);
}
fun('Carol');
// Carol
// Carol
// Mary