變數 result
就會是「a
函式執行完的結果」
把「呼叫 a
函式的回傳值」,用一個變數 result
去接收
因為 a
函式的回傳值是 'A',因此變數 result
就會是 ‘A’
function a(){
console.log('呼叫 A')
return 'A'
}
var result = a()
console.log('result: ', result)
output:
因為 var result = a()
這行,會先執行 a()
:
- 執行第一行
console.log('呼叫 A')
就會印出「呼叫 A」 - 執行第二行
return 'A'
,就會讓變數result
等於 'A'
然後再把變數 result
印出來:console.log('result: ', result)
就會是「result: A」
呼叫 A
result: A
傳參數只看順序
雖然我在呼叫 a
函式時,傳了兩個參數進去(50, 890),但是因為 a
函式只接收「一個參數」,因此就只會傳入「第一個參數(50)」
function a(number){
console.log('呼叫 A', number)
return 'A'
}
a(50, 890)
// output: 呼叫 A 50
在 function 裡面呼叫 function
function a(number){
console.log('呼叫 A', number)
return 'A'
}
function main(){
var result = a(789)
console.log(result)
}
main()
執行順序是
執行 main()
:
- 執行
main
函式的第一行var result = a(789)
:- 會先執行
a(789)
,參數number
就會是 789:先執行console.log('呼叫 A', number)
印出「呼叫 A 789」,再執行return 'A'
回傳 'A'
- 會先執行
a(789)
執行完畢。
這時,變數 result
就接收到了 a(789)
回傳的 'A'
- 再執行到
main
函式的第二行console.log(result)
就會印出 ‘A’ 了
output:
呼叫 A 789
A
上面的程式碼也可以這樣寫:
把變數 result
拿掉,直接寫 console.log(a(789))
,執行順序是:
- 先執行
a(789)
- 第一行:
console.log('呼叫 A', number)
會印出「呼叫 A 789」 - 第二行:
return 'A'
回傳 'A'
- 第一行:
- 然後再執行
console.log(a(789))
,就會把a(789)
的回傳值 'A' 給 log 出來
function a(number){
console.log('呼叫 A', number)
return 'A'
}
function main(){
console.log(a(789))
}
main()
output:
執行結果跟剛剛是一樣的
呼叫 A 789
A
只是把 a
這個 function 印出來而已
如果只有寫 console.log(a)
,因為我並沒有「呼叫 a
function」,所以就只會把 a
這個 function 印出來而已
function a(number){
console.log('呼叫 A', number)
return 'A'
}
function main(){
console.log(a)
}
main()
// output: [Function: a]
先把 function 宣告好,再做為參數傳入
把 function 當作參數來傳遞
把 a
function 當作參數傳入 main
function
console.log(arg)
出來的結果就會是 a
這個 function
function a(number){
console.log('呼叫 A', number)
return 'A'
}
function main(arg){
console.log(arg)
}
main(a)
// output: [Function: a]
這裡的參數 arg
就是 a
function
因此 console.log(arg === a)
會是 true
function a(number){
console.log('呼叫 A', number)
return 'A'
}
function main(arg){
console.log(arg === a)
}
main(a)
// output: true
所以,就可以用 arg()
來呼叫 a
function
function a(number){
console.log('呼叫 A', number)
return 'A'
}
function main(arg){
arg() // arg() 就等同於是 a()
}
main(a)
// output: 呼叫 A undefined
舉例:
在 function 裡面呼叫 function
function isPositive(n){
return n > 0
}
function isValid(number){
console.log('isValid')
console.log(isPositive(number))
}
isValid(100)
output:
isValid
true
改寫成:把 function 當作參數來傳遞
改成下面這樣寫,跟上面做的事情是一模一樣的:
把 isPositive
function 當作參數傳入 isValid
function
:heavy_check_mark: 注意!isPositive
後面不加小括號,才是「把 isPositive
function 當作參數傳入」的意思
因此,
- 參數
number
就會是 100 - 參數
fn
就會是isPositive
function,所以就可以用fn(number)
來呼叫isPositive(number)
function isPositive(n){
return n > 0
}
function isValid(number, fn){
console.log('isValid')
console.log(fn(number))
}
isValid(100, isPositive)
output:
isValid
true
注意!錯誤寫法:
把 isPositive
函式當作參數傳入時,isPositive
函式不可以加上小括號
執行下面的程式碼,會出現錯誤「fn is not a function」
錯誤的原因為:
isPositive()
就是「呼叫 isPositive
函式」的意思,因此 isValid(100, isPositive())
會先去呼叫 isPositive
函式,而因為 isPositive()
沒有傳入參數,所以 n 是 undefined,因此 return n > 0
就會回傳 false--> isPositive()
執行完會回傳 false
因此,isValid(100, isPositive())
就等於是 isValid(100, false)
,參數 fn
會被帶入 false,因此就會出現那句錯誤「fn is not a function」
isValid(100, isPositive())
是錯誤的寫法
function isPositive(n){
return n > 0
}
function isValid(number, fn){
console.log(fn(number))
}
isValid(100, isPositive())
在傳參數時,才宣告 function
要當作參數的 function,可以不用先寫好
在 isValid
函式傳參數時,才宣告 function,這個 function 要不要加上名稱都可以
function isPositive(n){
return n > 0
}
function isValid(number, fn){
console.log('isValid')
console.log(fn(number))
}
// 先把 function 宣告好,再做為參數傳入
isValid(100, isPositive)
// 在傳參數時,才宣告 function
isValid(100, function(n){
return n > 0
})
output:
isValid
true
isValid
true
map()
內建函式的用法
map()
的小括號裡面可以傳入一個 function,map()
會去執行這個 function,並且把陣列裡面的每個元素都當作參數依序傳入
function isNegative(n){
console.log('呼叫 isNegative', n)
return n < 0
}
let arr = [-3, 7, 8, 9, -20]
let arr2 = arr.map(isNegative)
console.log(arr2)
output:
呼叫 isNegative -3
呼叫 isNegative 7
呼叫 isNegative 8
呼叫 isNegative 9
呼叫 isNegative -20
[ true, false, false, false, true ]
map()
小括號裡面的 function,可以傳入三個參數:currentValue, index, array
為什麼要傳入這三個參數?
沒有原因,這就是規定好的
第一個參數是 currentValue
,也就是「陣列裡的每個元素」
let arr = [-3, 7, 8, 9, -20]
arr.map(function(currentValue){
console.log(currentValue)
})
output:
-3
7
8
9
-20
第二個參數是 index
,也就是「index 值」
第三個參數是 array
,也就是「整個陣列」
let arr = [-3, 7, 8, 9, -20]
arr.map(function(currentValue, index, array){
console.log(currentValue, index, array)
})
output:
-3 0 [ -3, 7, 8, 9, -20 ]
7 1 [ -3, 7, 8, 9, -20 ]
8 2 [ -3, 7, 8, 9, -20 ]
9 3 [ -3, 7, 8, 9, -20 ]
-20 4 [ -3, 7, 8, 9, -20 ]
自己實作出 map()
就是長這樣:
從實作可以看到:
map()
就是會幫我呼叫「我傳進去的 function」
function 裡面就是會帶入三個參數
function map(arr, fn){
let result = []
for(let i=0; i<arr.length; i++){
result[i] = fn(arr[i], i, arr)
}
return result
}
寫法一
用 console.log(getData())
把 getData()
的回傳值印出來
function getData(){
return {
data: 'I love you'
}
}
console.log(getData())
// output: { data: 'I love you' }
寫法二
上面的程式碼,可以用另一種寫法:
執行 getData()
就會呼叫 handleResult
函式
結果是一模一樣的
function handleResult(result){
console.log(result)
}
function getData(){
handleResult({
data: 'I love you'
})
}
getData()
// output: { data: 'I love you' }
寫法三
上面的程式碼,又可以用另一種寫法:
此時 getData(fn)
的 fn
就會是 handleResult
,因此,執行 fn()
就等於是執行 handleResult()
function handleResult(result){
console.log(result)
}
function getData(fn){
fn({
data: 'I love you'
})
}
getData(handleResult)
// output: { data: 'I love you' }
寫法四
上面的程式碼,又可以用另一種寫法:
在傳入 getData
函式時,才宣告 function(匿名函式)
function getData(fn){
fn({
data: 'I love you'
})
}
getData(function (result) {
console.log(result)
})
// output: { data: 'I love you' }
寫法五:改成箭頭函式
上面的程式碼,又可以用另一種寫法:
function getData(fn){
fn({
data: 'I love you'
})
}
getData(result => {
console.log(result)
})
// output: { data: 'I love you' }
function 傳參數只看順序(不管名稱),因此,參數要取什麼名字都可以
function getData(fn){
const data = {
data: 'I love you'
}
fn(data)
}
getData(abc => {
console.log(abc)
})
// output: { data: 'I love you' }