iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 15
1
Modern Web

For 前端小幼苗的圖解筆記系列 第 15

[JavaScript] 宣告 / hoisting / function

續前篇~接續脫稿(目錄)演出,來一波 JS ~ 下篇再回到原本軌道繼續未完的 CSS 人生……

Function

一連串的處理、一群指令的集合。

定義 function() 起手式

定義有名字的 (一般)function

function functionName(參數1, 參數2...) {
    ... 執行內容
  return 回傳值 (非必要)
}

定義沒有名字的 (匿名)function 

function(參數1, 參數2...) {
    ... 執行內容
  return 回傳值 (非必要)
}

有名字 V.S 沒名字的 function ?

  • 有名字的 function 可更方便的在不同的地方被呼叫。
  • 沒名字的(匿名)function
    • 可存進變數裡,透過變數被呼叫。
      var total = function() {
          ... 
      }
      
    • 或透過 IIFE 的方式執行: (感謝泰安老師補充、Eureka解惑)
      (function() {
          ... 
      })()
      
  • 呼叫時的差異:
    有名字 function 在其前或後,都可呼叫成功。
    指給變數的匿名函數,在呼叫時必須在其變數定義行之後才可呼叫。

Function被呼叫時

function myFunction(x) {
	return x
}
console.log(myFunction)
// 印出整個function code
console.log(myFunction(2)) 
// 印出function回傳值

基礎寫法

  • 定義與呼叫function時一定要加()
  • 回傳值要加 return
  • return行之後的程式碼都不會執行(return表function結束)

箭號涵式 Arrow Function

  • 函式運算式
    function show(text){
      console.log(text)
    }
    
  • 箭號涵式
    • 寫法1 : (參數)=>(回傳值)

      宣告 函數名稱 (參數1,參數2) => ( 回傳值 )

      • 回傳值可以省略return
        參數只有一個的時候可以省略括號

      宣告 函數名稱 參數1 => ( 回傳值 )

      • 參數只有1個的時候可以省略()

      宣告 函數名稱 () => ( 回傳值 )

      • 沒有參數的時候不能省略括號
    • 寫法2 : (參數)=>{涵式內容}

      宣告 函數名稱 (參數1,參數2) => {
      涵式內容
      ...

      }

    • 例1:

      var show = (text) =>{
        console.log(text)
      }
      
    • 例2 (內裡匿名涵式):

      setTimeout(()=> { 
          console.log('text')
      }),1000);
      

Hoisting 提升

  • 先呼叫 function 才定義 function,也能順利執行

    var fun = (name) =>{
      console.log(name)
    }
    
    fun("Amy");  /*Amy"*/
    
  • 先使用變數才宣告 var 時,不會噴錯、能順利執行 = undefined

    • 因為只有提升宣告、沒有提升定義值
          console.log(num)
          var num=1   // 是"undefined"、不是"Error"也不是1
      
  • 其他示例

    // 先使用變數再let宣告與賦值
    console.log(num1)
    let num1=1 
    // Uncaught ReferenceError: Cannot access 'num1' before initialization  
    
    // 先使用變數再var宣告與賦值
    console.log(num2)
    var num2=1   
    // undefined
    
    // 先使用變數才賦值但無宣告
    console.log(num3)
    num3=2
    // Uncaught ReferenceError: num3 is not defined 
    
    // 先使用變數才var宣告但無賦值
    console.log(num4)
    var num4   
    // undefined
    
    // 先使用變數才let宣告但無賦值
    console.log(num5)
    let num5   
    // Uncaught ReferenceError: Cannot access 'num5' before initialization 
    

Scope 作用域

  • global scope - 包含function外(全域)
  • function scope - function內
  • block scope - block 內

宣告變數&常數-var / let / const

var let const
意義 宣告變數 宣告變數 宣告常數
宣告時 可以先不指定值 ← (同var) 必須指定值
宣告後 可再次指定值 ← (同var) 不可改變值
宣告後 可再次宣告 不可再次宣告 不可再次宣告
範例 var xvar x = 2 ← (同var) const PI=3.14159
Scope作用域 涵式區塊 程式區塊{大括號內}包含迴圈/判斷 ← (同let)
  • 變數宣告不用指定類型
    可以隨時改變變數值的類型(儘量避免)
    型別資訊只存在在值或物件本身,變數本身沒有型別
  • 早期只能用var宣告變數,ES6增加 let、const
  • 如果沒有宣告而直接賦值(num=2)也會成功
    因為 JS 自動視為全域變數宣告(但最好不要這樣)
print=(content)=>{
  console.log(content)
}
  • Var
    1. var 沒有 function 時,scope 為整塊
      for(var i=0 ; i<5 ; i++){
        print(i)  //成功取得 i (=1、2、3、4)
      }
      print(i)    //成功取得 i (=5)
      
    2. var 在 function 內時,scope = function 內
      function 外讀不到
      function test(){
        for(var i=0 ; i<5 ; i++){
          print(i)  //成功取得 i (=1、2、3、4)
        }
      }
      print(i)    //無法取得 i
      
  • Let
    • let scope 只在{ }內
      { } 外就讀不到了
      for(let i=0 ; i<5 ; i++){
        print(i)  //成功取得 i (=1、2、3、4)
      }
      print(i)    //無法取得 i
      

關於 let / var / const 作用域也是 Junior 工程師滿常見的面試考題嘿!這篇寫的不夠完整嗎?再多 google 幾篇讀讀各種解釋,並直接邊寫 JS 邊 try 結果來理解它們的差異性吧!


參考資料:


個人 Blog: https://eudora.cc/


上一篇
[JavaScript] 基礎語法 / 資料型態
下一篇
[JavaScript] DOM 操作 & 陣列操作 ( forEach / map / reduce / filter / find / some / every )
系列文
For 前端小幼苗的圖解筆記30

1 則留言

0
taiansu
iT邦新手 5 級 ‧ 2020-09-30 00:21:33

晃過來又發現被 cue 了 XD 大部份的理解蠻不錯的,整理的也很好,加油!

是說匿名函式可以直接執行喔。像這樣:

(function(x) {
  console.log(x);
})(100)
Eudora iT邦新手 5 級 ‧ 2020-09-30 00:55:19 檢舉

一定要Cue一下的 XD
感謝泰安老師補充,立馬補回文章矣~

好哦,會加油 der!希望順利寫完(深呼吸)

taiansu iT邦新手 5 級 ‧ 2020-09-30 01:32:17 檢舉

加油!

/images/emoticon/emoticon12.gif

我要留言

立即登入留言