【JavaScript】作用域、作用域链和闭包

  • A+
所属分类:Web前端
摘要

作用域是指可访问的变量和函数的集合。作用域可分为全局作用域和局部作用域。


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, 最后将两个子函数返回(一个可直接放回,多个可放到对象中返回。)。  这样,在函数外面可以调用子函数访问函数内部的变量, 这两个子函数便实现了闭包的功能。