1. 程式人生 > 其它 >【js重學系列】作用域

【js重學系列】作用域

作用域

談起閉包首先要理解作用域,什麼是作用域?
在 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