今天我們將講解JavaScript Function的Closure(閉包)概念
Closure是作用域的一種形式,用於將函式『外部』作用域中的變數保留在函式內部作用域中
以下舉例:
let c = 100;
function sum(a, b){
return a + b + c;
}
console.log(sum(3, 4)); // 107
Sum函式執行內容為返回a+b+c的數值
然而在函式定義內容中,根本沒有c,只有參數a和b而已
那最終結果從何而來呢?
c就是透過Closure,一路向外尋找,最終於Global Scope裡找到變數c
下方兩個例子中我們都調用sayHi()和sayHi2()函式
兩個例子差別在於,sayHi2()是否定義在sayHi()裡頭,第一個例子是,二則否
//範例一
let myName1 ='Jeremy'
function sayHi(){
let myName1 = 'Kevin'
console.log(myName1 + '說你好');
function sayHi2(){
console.log(myName1 + '說你好');
}
sayHi2()
}
// 調用sayHi函式
sayHi() //Kevin說你好, Kevin說你好
//範例二
let myName1 ='Jeremy'
function sayHi(){
let myName1 = 'Kevin'
console.log(myName1 + '說你好');
}
function sayHi2(){
console.log(myName1 + '說你好');
}
sayHi() //Kevin說你好
sayHi2() //Jeremy說你好
為何運行結果會有所不同呢?
Closure會先在function自身範圍內找,找不到才會往外層找
在範例一中:
sayHi()本身即有定義myName變數,因此第一個console.log結果會是Kevin說你好
sayHi2()本身則是沒有定義myName變數,因此向『外』尋找,先到sayHi()的大括號內,最終找到myName變數,因此第二個console.log結果也是Kevin說你好
在範例二中:
sayHi()本身即有定義myName變數,因此第一個console.log結果會是Kevin說你好
sayHi2()本身沒有定義myName變數,也一樣會向『外』尋找,最終在Global scope處找到,最終結果為Jeremy說你好