1. 程式人生 > 程式設計 >詳解JavaScript作用域、作用域鏈和閉包的用法

詳解JavaScript作用域、作用域鏈和閉包的用法

1. 作用域

作用域是指可訪問的變數和函式的集合。

作用域可分為全域性作用域和區域性作用域。

1.1 全域性作用域

全域性作用域是指最外層函式外面定義的變數和函式的集合。

換言之,這些最外層函式外面定義的變數和函式在任何地方都能訪問。

舉個例子:

// 最外層定義變數
var a = 1;

console.log(a); // 最外層可以訪問

function fnOne() { // 最外層函式
  
  console.log(a); // 函式內可以訪問
  
  function fnTwo() { // 子函式
    console.log(a); // 子函式內也可以訪問
  }
}



// 說明
在最外面定義一個變數,不僅在最外面可以訪問,
在函式內也能訪問,在函式的子函式內也能訪問。

1.2 區域性作用域

區域性作用域是指在函式內部定義的變數和函式的集合。

換言之,這些在函式內部定義的變數和函式,在函式外面是無法訪問的,只能在函式內部(包括函式的子孫函式)訪問。

舉個例子:

function fnThree() {
  // 在函式內定義變數
  var b = 2;
  
  console.log(b); // 函式內部可以訪問
  
  function fnFour() {
    console.log(b); // 子函式內也能訪問
  }
}
// 函式外不能訪問
//console.log(b); 


// 說明
在函式 fnThree 中定義一個變數 b ,在函式內可以訪問,
在子函式 fnFour 中也能訪問,但在 函式 fnThree 外是不能訪問的。

2. 作用域鏈

從上面的兩個例子可以看出,最裡層的子函式不僅可以訪問最外層函式內的變數,還能訪問最外層函式外的全域性變數。

這是因為,在建立最外層函式的時候,會把全域性作用域拿過來,然後在建立子函式時候,又會把最外層的作用域(包括全域性作用域)拿過來,就這樣一環扣一環,就形成了作用域鏈。

所以,作用域鏈是指內層函式擁有外層函式到最外層(最外層函式外,全域性)的所有作用域列表。

3. 閉包

閉包就是能夠讀取其他函式內部變數的函式。(——百度百科)

從上面的第二個例子可知,函式外是不能訪問函式內部定義的區域性變數,但是閉包提供了可能。

舉個例子:

function User() {
	// 定義私有變數
	var userName = "default";
	
	// 提供 setUserName() 方法
	function setUserName(uName) {
		userName = uName;
	}
	
	// 提供 getUserName() 方法
	function getUserName() {
		return userName;
	}
	
	// 將方法對外開放
	return {
		set: setUserName,get: getUserName
	}
}

var user1 = User();
user1.set('tom');
console.log(user1.get());
var user2 = User();
user2.set('jack');
console.log(user2.get());

// 說明
User 函式內部定義變數 uesrName ,
並在內部定義兩個子函式操作 userName,
最後將兩個子函式返回(一個可直接放回,多個可放到物件中返回。)。

這樣,在函式外面可以呼叫子函式訪問函式內部的變數,
這兩個子函式便實現了閉包的功能。

以上就是詳解JavaScript作用域、作用域鏈和閉包的用法的詳細內容,更多關於JavaScript作用域、作用域鏈和閉包的資料請關注我們其它相關文章!