JavaScript function 紀錄1
function 背後運算的邏輯
- 只要使用 function Global Execution Context(執行全域上下文)就會被建立,這時候會一併建立 this,global object (window)
函式物件(function)
- 就是一般物件外加可以被呼叫的能力
- 將 function 儲存成變數
- function 當成參數代入另一個 function 中
- 在 function 中回傳另一個 function
- 分割片段功能 & 多層級組合
1 | var a = function () { } |
- 特色
- 一級物件 (First-class object)
- 可以被動態建立、可以指定給變數、可以複製給其他變數
- 可以擁有自己的屬性或方法 (一般物件特性)
- 提供了變數的作用域 (Scope)
- 一級物件 (First-class object)
- 語法
- name
- 函式名稱
- param
- 要被傳入函式的引數名稱,一個函式最多可以擁有 255 個引數
- statements
- statements 構成了函式內容的陳述式
- name
1 | function name([param[, param[, ... param]]]) { |
function expressions 和 function declaration - 函數表達式&函數語句
- 有什麼特性
- 建立函式的方式
- 判斷
- expressions
- 存成一個變數 hoisting 會產生錯誤
- 無法立即知道該匿名函式的功能,可讀性較差
- declaration
- 匿名函式不會直接回傳任何的值
- 最開始該函式就會透過 hoisting 先被儲存在記憶體中
- expressions
函式表達式(function expression) | 函式宣告式(function declaration) | |
---|---|---|
具名函式 | var add = function add(a, b) { return a + b}; add.name // add | function add(a, b) { return a + b }; add.name // add |
匿名函式 | var add = function (a, b) { return a + b }; add.name // add | function (a, b) { return a + b } // Uncaught SyntaxError |
hoisting
- 有什麼特性
- 變數和 function 的宣告在編譯階段中先被放入記憶體,實際在程式碼中位置還是一樣
- 當 function 與變數/常數同時提升時,function 的優先程度高於變數/常數
- 如果 hosting 時有兩個 function,最後的 function 會被 hosting
- 判斷
- function 會被完全提升 所以能呼叫
- 變數宣告 只有所進行的指定(assignments)動作不會提升 所以產生錯誤
1 | // 全域變數 |
Scope - lexical scoping(語彙範疇)
- 「鴨子轉圈圈」就是把大家都匡在這裡,好好待不要亂跑,想出去可是有條件的
- 有什麼特性
- 「切分變數有效範圍的最小單位是 “function” 」= scope
- 避免相同變數所造成的衝突,這當中包含了避免污染全域命名空間和模組的管理
- 判斷
- 能夠被存取的位置
- global
- function
- 找尋一個變數的 lexical scoping rule
- 會從此變數所存在的 function 開始找,如果找到了就返回該變量,如果找不到就往上一層繼續找以此類推直到 global 的環境
- scope chain 範圍鏈是在函式被定義的當下 決定的,不是看呼叫(return)的時候決定
- 可以找到上一層變數&function
- function 的 execution context 已經離開 execution stack 了,但這個 execution context 在記憶體中所建立的位置並沒有消失,因此 JS 仍然可以透過 scope chain 找到變數(scope chain 跟變數 close 在一起)而這樣的現象就稱為 closure
- 可以找到上一層變數&function
- 能夠被存取的位置
1 | let a = 6 |
closure
- 有什麼特性
- 不想讓變數直接被操作或修改
- 避免變數汙染全域的問題 - IIFE 的應用
- 透過 closure 讓 function 能夠有 private 變數,讓變數保留在該 function 中避免暴露在 global 導致運算出錯
- closure 會 keep 住變數佔用記憶體空間,如果這變數沒有在使用 JS 會自己回收
- 判斷
- 運用在巢狀函式的定義中
- function 內 return 另一個 function,通常就是有用到 closure 的概念
- 每執行一次 function,就會產生一個新的 execution context,而且即使有多個參數值被儲存在記憶體中,JS 會自己找到屬於該 execution context 的變數
1 | // 基本 clouser 範例 |
- 範例
1 | // 點擊按鈕取出對應的文字 |
return
- 終止函式執行 & 指定函式返回的值
- 沒有 return 陳述式(或者光是 return,沒有值),JavaScript 便會傳回 undefined
- 呼叫 return 的地方後,函式會立即停止
- return [[expression]]
1 | // return 沒有值為 undefined |