function 額外補充


Posted by saffran on 2021-02-05

變數 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' }

#javascript







Related Posts

什麼是宣告式 UI 的 Android Compose

什麼是宣告式 UI 的 Android Compose

C# 動態生成圖片記憶體釋放

C# 動態生成圖片記憶體釋放

Git 學習筆記

Git 學習筆記


Comments