一.什么是作用域
就是可以在一个容器中去储存我们所声明的变量,并且可以动态的去添加和修改,并·将这种能力给与程序,如果没有了作用域,程序的功能性会变弱。
二.理解作用域
引擎,从头到尾负责整个 JavaScript 程序的编译及执行过程。
编译器 引擎的好朋友之一,负责语法分析及代码。
作用域 引擎的另一位好朋友,负责收集并维护由所有声明的变量,并实施一套非常严格的规则,确定当前执行的代码对声明变量的访问权限
4.他们之间的对话
var a = 2;
//首先程序开始了执行,编译器开始去解析代码,首先编译器看见了var a;
//会去向作用域询问我要在当前作用域声明a了,你帮我看一下有没有在当前作用域声明a了。
//如果声明那么会去跳过声明这一步骤,如果没有,则开始声明。
//继续执行程序,程序又去看见了a = 2,编译器会去问作用域这个作用域有a这个变量吗,
//如果有的话,告诉我一说,作用域说:"这个作用域有a的兄弟"。
//编译器说:"谢谢了,看我给他赋值",程序执行完毕。
//这个还涉及到了变量提升会在后面的文章讲。
5. LHS 查询和RHS查询。
LHS查询,在我们的例子中给a赋值为2就是一个LHS查询,通俗来讲,可以将对变量进行赋值操作的都会是一个LHS查询。
RHS查询,在我们的例子中给a声明就是一个RHS查询,通俗来讲,可以将对变量进行查询是否声明操作的都会是一个RHS查询。
三.作用域的嵌套
作用域的嵌套一句话就可以概括,那就是在当前作用域查找的变量,如果没有找到,依次去往最上级的作用域去找,直到到全局作用域为止。
function foo(a) {
console.log( a + b );
}
var b = 2;
foo( 2 );
//首先我们去调用了foo这个函数,引擎先会去对a进行一个RHS查询,在这里a会是这个函数的参数
//第二步,对b进行RHS查询由于在foo这个作用域中没有去声明这个变量,作用域会说:"走开,我没有看见b"
//引擎会说:"兄弟,帮我上全局作用域中找一下呗,咱俩认识这么久了"
//作用域会说:"那我就帮你找找吧,哟,还真有,给你吧,b是个2"
//引擎说:"谢谢了",继续执行,a+b打印出来4
四:作用域的漏洞
js这门语言是有很多bug的,作用域也有一个,那就是LHS,例子如下:
function foo(a) {
console.log( a + b );
b = a;
}
foo( 2 );
//在这个例子里面和上面作用域的嵌套例子差不多,区别是我没有对b进行声明,
//那么在对其进行RHS查询的时候,会报出 Uncaught ReferenceError: b is not defined
//作用域告诉我我都没看见b,你都没有什么就调用是不是异想天开了。程序终止无法继续运行。
2.热心的作用域,例子如下:
b = 2
console.log(b)
//在这个例子里面我对没声明的b直接进行LHS查询,你可能会因为他也会报错,但是他不会。原理如下
//首先在es5中引入了严格模式,在那之前js都是相对宽松的,热心的作用域会在你进行LHS查询的时候,
//如果这个变量不存在,它会帮你声明,也就是上面的代码会转换为var b = 2;console.log(b)