JavaScript的作用域

JavaScript的作用域

作用域总共有两种模式,词法作用域动态作用域

词法作用域是由开发者在写代码时,将变量和块作用域写在哪里而决定的。

动态作用域是运行时确定的。

JavaScript只有词法作用域,也就是我们说的作用域链,一层一层的嵌套,但this机制很像动态作用域,它也是在运行时决定的。

function foo(){
    // 词法作用域 2  -- 动态作用域 3
	console.log(a); 
}

function bar(){
	var a = 3;
	foo();
}

var a = 2;
bar();

这段代码,以词法作用域来看会输出2,如果是动态作用域的模型,会输出3,因为动态作用域是在运行时决定的,当foo()无法找到a的变量引用时,会顺着调用栈在调用foo()的地方去找a,而不是在词法作用域链上去找a,而foo是在bar里调用的,在bar里找到了值为3的a,所以动态作用域的模型会输出3。

上面只要了解就够了,接下来主要是说函数作用域的事

function foo(){
	var a = 1;
	console.log(a); // 1
}

function bar(){
	var a = 2;
	console.log(a);// 2
}

foo();
bar();

从这里可以看出,在不同的函数中,相同名字的变量,但它们并不是同一个变量,这就是函数作用域。

接下来看稍微复杂的

function bar(){
	var a = 2;
	console.log(a);// 2

	function foo(){
		var a = 1;
		console.log(a); // 1
	}
	foo()
}

bar();

经过这两段代码,可以知道不管函数是否嵌套,里面的同名变量都是互不影响的。

函数作用域是如何查找变量的

var a = 1;
var b = 2;
var c = 10;

function bar(){
	b = 10; // 通过LSH引用,找到了全局作用域的b,再赋值
	var c = 20;
    
	function foo(){
		console.log(a); // 1
		console.log(c); // 20
	}
    
	foo()
}

bar();
console.log(b); // 10

词法作用域在查找变量是往作用域一层一层找的。

foo函数要输出a,会先在自己的作用域里找a这个变量,找不到,就会去父级作用域,这里是bar的作用域找,但是很明显,依然找不到,所以再到上一层作用域,这时已经到全局作用域了,发现找到了,于是就输出a的值,如果全局作用域也没有找到就会报错。

而foo在找c的时候,已经在bar的作用域找到了,所以就不会再去全局作用域找了。

而bar的b,也是这样,在自己的作用域找不到,就去它的父级作用域找。

原文地址:https://www.cnblogs.com/tourey-fatty/p/12111924.html