作用域是什么?
任何编程语言都有作用域的概念,简而言之,作用域就是函数以及变量的访问范围。即作用域控制着变量与函数的可见性和生命周期。
1.变量作用域分为全局作用域和局部作用域;


在以上代码中,函数变量外的变量拥有全局作用域。比如图一图二的 var n=2;
未定义直接赋值的变量自动声明为拥有全局作用域。如图二a=1;
局部作用域一般只在固定的代码片段内可访问到,最常见的例如函数内部,所以在一些地方会把这种作用域成为函数作用域。
图一中,a是函数内部声明并赋值,拥有局部作用域,只能带函数fn内部使用,在fn外部使用就会报错,这就是局部作用域的特性,外部无法访问。
2.词法作用域:静态作用域。在js预解析阶段,确定变量的作用域。js中的作用域的工作方式通常指的是词法作用域,这句话意思就是作用域在写代码的时候就确定了。
在词法作用域中规定,变量的作用域由其定义的位置决定,而不是使用的位置。
在词法作用域下,只有函数可以限定作用域。
变量的搜索原则
1,首先在当前作用域查找,如果找到就直接使用该变量的值。停止查找。
2,如果没有,就往上一层找,如果有就是用,停止。
3,没有 继续找。一直到全局作用于。如果找到就是用。否则,就抛出引用异常。
3.js预解析
3.1 语法分析: 分析js代码是否满足js语法的定义。如果在分析某行时,检查出不符合语法规则就直接在语法分析阶段(预解析阶段)抛出语法异常
目的:保证js代码符合语法规则,能被正确执行。
/**预解析过程:
*1.把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值
*2.把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
*先提升var,再提升function
*注意:
*预解析中变量的提升只会在当前作用域中提升,提升到当前的作用域的最上面
*函数中的变量只会提前到函数作用域的最前面,不会出去
*/

4.作用域链
通俗地讲,当声明一个函数时,局部作用域一级一级向上包起来,就是作用域链。
执行过程为:先在同一个作用域寻找变量,如果没有将要往上一级作用域寻找,如果到顶级作用域没有找到变量,将要创建一个变量。
