函式
基本語法結構
//匿名函式 function() {} //有名稱的函式 function foo() {}
傳⼊參數預設值
傳⼊參數預設值是在眾多ES6新特性中的其 中⼀個,它改善了⻑期以來在JavaScript中都要使⽤技巧性的作法來設定函式傳⼊參數的預設值的語法。
函式的”傳⼊參數”常會看到兩個不同的英⽂字詞
- parameters: 指的是在函式的那些傳⼊參數名稱的定義。我們在⽂章中會以”傳⼊參數定義名稱”來說 明。
- arguments: 指的是當函式被呼叫時,傳⼊到函式中真正的那些值。我們在⽂章中會以”實際傳⼊參數值”來說明。
邏輯或(Logical OR)(||)運算符
邏輯或(Logical OR)(||)運算符在運算時,如果當第1個運算⼦為”falsy”時,則回傳第2個運算⼦。否 則,將會回傳第1個運算⼦。
console.log(‘foo’ || ‘bar’) // ‘foo’
console.log(false || ‘bar’) // ‘bar’
“falsy”包含了0, -0, null, NaN, undefined, ‘’(空⽩字串),當然也⼀定包含了false值
布林相關的邏輯運算語法
例子:
if (isValid) {
// ...stuff...
}if (!name) {
// ...stuff...
}if (!collection.length) {
// ...stuff...
}
注意
- 空物件({})與空陣列([])都不是falsy成員之⼀,實際上對於物件類型的值完全無法判斷
- 如果預設值可以是0或’’(空⽩字串),甚⾄可以是null,這種⽅式判斷不出來,要額外再作判斷
ES6的傳⼊參數預設值
ES6後的函式傳⼊參數中,可以指定預設值
const link = function (point = 10, url = 'http://google.com') {
//...
}
注意
- 只有在傳⼊參數為undefined時或是不存在,才會使⽤預設值,null並不會。
傳⼊參數預設值裡可以⽤表達式
呼叫其他的函式當傳⼊參數的預設值
傳⼊參數預設值的求值是每個函式呼叫獨⽴的(Evaluated at call time)
傳⼊參數預設值會隱蔽外在的作⽤域
傳⼊參數預設值的TDZ(Temporal Dead Zone, 時間死區)作⽤
傳⼊參數預設值使⽤物件、其他函式與this
- 是直接呼叫foo(),this會指到window或全域物件中,x相當於window或全域物件。y沒這屬性存 在,所以是undefined。
- 按照傳⼊參數,x會是這個物件,y沒給所以⽤預設值,y是this.value,此時this會指到window或全域物件中,y 沒這屬性存在,所以是undefined。
- ⽤了call⽅法,裡⾯是⼀個物件帶有value屬性,作為呼叫這個函式的擁有者物件,所以this會指到 這個物件,x為這個物件,y是裡⾯的value值,也就是’^^y~’字串。
傳⼊參數預設值 其他函式
必要的傳⼊參數
如果你想要讓某個傳⼊參數是必要的,如果在使⽤時沒給傳⼊參數就報錯
預設值的位置並沒有限制
箭頭函式也可以使用
const func = (x = 100) => x * 2
傳⼊參數預設值中可以使⽤解構賦值
傳入參數預設值 其餘參數
內部(巢狀)函式
內部函式可以獲取到外部函式所包含的環境值,例如外部函式的傳入參數、宣告變數等等。
而內部函式又可以成為外部函式的回傳值,所以當內部函式接收到外部函式的環境值,又被回傳出去,內部函式間接變成一種可以讓函式對外曝露包含在函式內部環境值的溝通管道,這種 結構稱之為”閉包(closure)”。
作用範圍(scope)
var ”全域變數”
if (true) {
var x = 5
}
console.log(x) //5
使用 let
if (true) {
let y = 5
}
console.log(y) //y is not defined
回調 callback
- 確保程式時機與關連
- 便於維護
提升(Hoisting)
- 函式運算式不會被提升。
- 當函式與變數/常數同名稱而提升時,函式的優先程度高於變數/常數。
- 不同 <script>包圍,即視為不同的檔案,因此變數宣告不會被拉升到另一支檔案的頂端。
匿名函式與IIFE
中文稱之為”立即呼叫的函式表達式”
IIFE的主要用途,例如分隔作用範圍,避免全域作用範圍的污染,避免在區塊中的變數提升(Hoisting)。
函式定義方式
// 1. 函式定義
function sum(a, b) {
return a + b
}// 2. 函式表達式
const sum = function (a, b) {
return a + b
}// 3. 箭頭函式
const sum = (a, b) => a + b
建議使用第1.種 第3.種
撰寫建議
- 避免在傳⼊參數預設值中產⽣副作⽤,修改到其他共享的變數值。
- 總是把有傳⼊參數預設值的參數放在函式的圓括號中的後⾯。
- 不要更動傳⼊參數的值,不要重新指定傳⼊參數的值。
- 不要用arguments物件,改用其餘參數