[JS] Function基本介紹-3
TL;DR
本篇介紹:
- 函式的參數
- arguments
- this
- 區域變數以及透過範圍鏈取得的外部變數
- 將函式視為參數傳入(即callback function)
參考資料
- 呼叫函式時,到底有多少個參數 / 變數可供使用? | Casper
- JavaScript 一級函式 (First Class Functions) | Casper
- 函式參數預設值 - 基礎範例(Default Arguments) | IT
相關連結
- 一級函式(First-class Function) | MDN
- 預設參數(Default parameters) | MDN
- Arguments對象(The arguments object) | MDN
函式的所有參數
透過簡單的範例,我們先來了解一個函式內,可以運用的參數有哪些。
const globalVariable="全域變數";
const obj={
fn(param){
const localVaribale="區域變數";
console.log('param',param);
console.log('localVaribale',localVaribale);
console.log('globalVariable',globalVariable);
console.log('arguments',arguments);
console.log('this',this);
}
}
obj.fn('作為參數傳入的字串1','作為參數傳入的字串2',3,4,null,undefined,false,true);
// param 作為參數傳入的字串1
// localVaribale 區域變數
// globalVariable 全域變數
// arguments
// Arguments(8) ['作為參數傳入的字串1', '作為參數傳入的字串2', 3, 4, null, undefined, false, true]
// this
// {fn: ƒ}
執行結果圖示
參數與區域變數Hoisting
我們都知道,javascript在宣告變數的時候具有Hoisting的特性。
透過以下範例來釐清在函式內所定義的變數的hoisting,與外部傳入參數的順序。
結論
- 外部傳入參數的創造階段先於內部變數的創造階段
- 參數的變數名稱可以透過重新賦值覆蓋掉外部傳入的內容
首先先驗證參數變數名稱可以透過重新賦值的方式來覆蓋:
function callName(myName) {
console.log(myName);
var myName;
console.log(myName);
myName='杰倫';
console.log(myName);
}
callName('小明');
// 小明
// 小明
// 杰倫
中間的var myName
其實沒有產生任何影響,直接拿掉運作結果也會相同:
function callName(myName) {
console.log(myName);
myName='杰倫';
console.log(myName);
}
callName('小明');
// 小明
// 杰倫
note
如果中間var
改為let
則會被視為重複宣告變數。而改為const
除了檢查是否重複宣告以外,還需要給定初始值。
所以建議都使用ES6的let
以及const
來宣告變數,可以避免許多錯誤。
再來看另一個範例
因為使用function所宣告的函式,在hoisting時會移動到作用域的最前方,那麼我們來確認一下是否會先於參數變數:
function callName(myName) {
console.log(myName);
function myName(){}
myName='杰倫';
console.log(myName);
}
callName('小明');
// ƒ myName(){}
// 杰倫
如果function的hoisting早於參數,那麼印出來的就還會是小明。可以看到funciont myName
移動到第一個console.log之前,但是仍然是在參數傳入之後,所以印出來的會是f myName(){}
。