JS踩坑筆記 - function 宣告


Posted by Nacho on 2020-09-20

Online JS 執行環境(nodejs)
https://repl.it/languages/nodejs

關於 function 宣告的幾個重點:

  • JS呼叫function,不會貼心會你做args的檢查,傳少出現undefined,傳多會忽略
  • JS的function通常被用來做以下用途:
    • 指定給變數
    • 當作arg傳給其他funciton使用(不加括號)
    • 作為function的回傳值
  • Function的宣告方式可分成兩種
    • 宣告式:建立在程式執行階段之前,可以在程式內任何地方都可以呼叫
    • 表達式:建立在程式執行階段,在這之前只有宣告變數,還沒有值傳入
    • 補充:表達式的生命週期由變數決定的!!移除變數才能GC

這是宣告式 function declaration

想在哪裡呼叫都可以!!!

myFunc(10, 20);
var myFunc = function(a, b) {
  console.log('a:', a, ', b:', b);
}
myFunc(10, 20);

這是表達式 function express:有匿名和具名兩種

要注意呼叫的位置!!!

myFunc(10, 20) // 放這邊會噴錯! 因為myFunc還是undefined
var myFunc = function(a, b) {
  console.log('a:', a, ', b:', b);
}
myFunc(10, 20) // 放這邊ok! 因為myFunc已經是function了

具名的額外好處是會顯示回傳錯誤!

var myFunc = function show(a, b) {
  return x
}
myFunc(10, 20) // error: .... at show

表達式的另一個觀念是具名函數只有在函式內部有效

  • 當函式要自己呼叫自己具名就派上用場 <= 遞迴
var myFunc = function factorial(n) {
  let x = (n == 1 ? n : n * factorial(n-1));
  console.log(n + " > " + x)
  return x
}
myFunc(5) // 120

還有一種表達式,是一次性的 => IIFE

  • IIFE(Immediately Invoked Function Expression)稱可立即執行函式
  • JS一看到它便會立即執行,然後把執行後的結果傳給變數
  • 它必須是表達式或者用()將function包起來

先來看一般表達式的執行結果

var myFunc = function() {
  return "hello";
}

console.log(myFunc) // return function itself
console.log(typeof myFunc) // type is function
console.log(myFunc()) // hello

再來看使用IIFE的執行結果,可以發現執行完,function就不存在了

var myFunc = function() {
  return "hello";
}();

console.log(myFunc) // hello
console.log(typeof myFunc) // type is string
console.log(myFunc()) // error => myFunc is not function

IIFE搭配參數

var myFunc = function(a, b) {
  return a+b;
}(10, 20);

console.log(myFunc) // 30

此外,如何宣告一個IIFE呢?

  • 錯誤宣告:匿名、宣告式
  • 不採用表達式...那就要用()包起來
function() { // 錯誤版
  console.log("hello");
}();

function myFunc() {  // 錯誤版
  console.log("hello");
}();

(function myFunc() {  // 正確
  console.log("hello");
})(); // 或者也可以

(function myFunc() {  // 正確
  console.log("hello");
}());

關於箭頭函式

  • 沒有this(指向全域), arguments(無法在裡面查參數)可以用
  • 沒有參數的宣告,var myfunc = () => console.log("hello");

callback

  • callback是把function當作參數傳入使用
  • 通常用於延續 Async Job 完成後的程式執行
function func(x,y,cb) {
  let num = x+y;
  cb(num);
}

func(10, 20, (num) => {
  console.log("num: ", num); // num: 30
});
  • 值得注意是如果把function當參數使用,因為不會回傳任何東西,所以不需要加()
function alertFunc() {
  console.log("Hello!");
}

setTimeout(alertFunc, 3000);

參考

學習筆記參考:Javascript精選16堂課:網頁程式設計實作


#javascript #function #IIFE #function expression







Related Posts

CS50 Lec7 - SqLite SameTime Update Error - Transaction

CS50 Lec7 - SqLite SameTime Update Error - Transaction

5.  SpringBoot使用jms錯誤處理延(1)

5. SpringBoot使用jms錯誤處理延(1)

[ Vue3筆記 ] 封裝打 API + loading狀態

[ Vue3筆記 ] 封裝打 API + loading狀態


Comments