【js重學系列】作用域
阿新 • • 發佈:2021-12-25
作用域
談起閉包首先要理解作用域,什麼是作用域?
在 JavaScript 中, 作用域為可訪問變數,物件,函式的集合。
區域性作用域
- 變數在函式內宣告,變數為區域性作用域。
- 區域性變數:只能在函式內部訪問。
- 因為區域性變數只作用於函式內,所以不同的函式可以使用相同名稱的變數。
- 區域性變數在函式開始執行時建立,函式執行完後區域性變數會自動銷燬。
全域性作用域
- 變數在函式外定義,即為全域性變數。
- 全域性變數有 全域性作用域: 網頁中所有指令碼和函式均可使用。
- 如果變數在函式內沒有宣告(沒有使用 var 關鍵字),該變數為全域性變數。
變數生命週期
- JavaScript 變數生命週期在它宣告時初始化。
- 區域性變數在函式執行完畢後銷燬。
- 全域性變數在頁面關閉後銷燬。
- 函式引數只在函式內起作用,是區域性變數。
- 在 HTML 中, 全域性變數是 window 物件: 所有資料變數都屬於 window 物件。
var b = 1; function a() { var c=1; console.log('b:',++b); console.log('c:',++c); } a() //b: 2 c: 2 a() //b: 3 c: 2 a() //b: 4 c: 2 可以看出變數的生命週期,區域性變數在函式執行時建立,執行完畢後銷燬,所以每次呼叫都是開闢新的記憶體地址,都是新的值,全域性變數在頁面關閉後銷燬,所以每次呼叫都會累加值
作用域鏈
在ES5中只存在兩種作用域, 1️⃣全域性作用域 2️⃣區域性作用域
當訪問一個變數時,直譯器會首先在當前作用域查詢標示符,如果沒有找到,就去父作用域找,直到找到該變數的標示符或者不在父作用域中,這就是作用域鏈。 值得注意的是,每一個子函式都會拷貝上級的作用域,形成一個作用域的鏈條。
var x = 1; var y = 1; function demo() { var x = 2 function demo2() { var x = 3; console.log(x); //3 console.log(y); //1 } demo2() } demo()
塊級作用域
for (var i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i); //333
},2000)
}
for (let i = 0; i < 3; i++) {
setTimeout(function() {
console.log(i); //012
},2000)
}
塊級作用域的理解:
var定義的沒有塊級作用域,迴圈三次結束後,才會執行定時器裡的回撥函式,然後找到父級作用域,由於父級作用的i沒有塊級作用域,所以訪問父級的i的時候,i的值已經變成了3
let定義的又塊級作用域,去找父級的i的時候i的值時每次迴圈傳入的值,不會被後面的更改,所以能輸出012