JS之做用域浅谈

这几天看了一下JS高级程序设计里的介绍做用域的章节,也参考了网上的资料,如今结合着本身的理解,给你们分享一下我本身对JS做用域的理解。前端

做用域及执行环境

这里有三个重要的概念:执行环境、做用域、变量对象函数

(JS高级程序设计解释)
执行环境 :定义变量或函数可访问的其余数据,来决定它们的行为。
变量对象 :保存执行环境中定义的变量和函数。
做用域链 :保证对环境中定义的变量和函数的有序访问。设计

通俗来讲,执行环境和做用域就是变量或函数有效执行所在的一个环境。
总结一下这三者的关系:每一个执行环境执行时都会产生一个做用域,做用域前端都有一个变量对象来保存环境中的变量和函数。code

知道这3个重要概念后,要想搞清做用域,就要先清楚JS程序的预解析过程
JS程序开始执行时会先解析语法(检查错误等等)、解析内存,而后把function、var解析到变量对象里。
这里注意解析var变量时只是会把变量名称解析,而等到程序运行到变量赋值时才会向变量赋值。对象

var a="A";
function test(){
    console.log(a);//undefined
    var a="B";
}
test();

这段代码的第一个console.log之因此会是undefined,缘由是函数内部的a变量在预解析时已经被解析到变量对象里,但没被赋值。因此函数执行时找到函数里未被赋值的a变量,输出undefined。内存

搞清楚预解析后,在判断做用域范围
由于做用域的查找顺序是由局部做用域一步步地往上找,直到找到声明的变量和函数或已经到了全局做用域。因此局部的做用域能够访问到外部做用域的变量,而外部做用域访问不到内部做用域的变量。作用域

相关场景

var a="A";
function test(){
    console.log(a);//“A”
    a="B";
}
test();
console.log(a);//"B"
function test(){  
      b();//函数b会被预解析,所以能够调用,执行了输出1;
      var a=1;
      function b(){
          console.log(1);
          console.log(a);//undefined
          var a=2;
      }
}
test();

以上例子参考网上资料。io

总结

要想搞清做用域,首先要搞清预解析,而后判断做用域范围,先判断本层环境有无声明及赋值,若是有声明,则判断调用前是否赋值。若是找不到声明,则一层层往外部的做用域找,直到全局环境也找不到时,一般就会报错。console

若是有解释的不对或不清晰的,欢迎留言讨论。function

相关文章
相关标签/搜索