日期:2014-05-16  浏览次数:20379 次

谈谈对js作用域的理解与疑问,请各位指正。
近来看了nicholas写的《javascript 高级程序设计》这本书,在讲到下列内容

这是原文: “当代码在一个环境中执行时,会创建由变量对象构成的一个作用域链。”

通过原文的意思是:如果有一个function, 只有当这个function被调用时,它才会在这个function创建一个作用域链。

比如这个例子
function test() {
  var  s = 66;
      function sub() {

           alert(s);
      };
      sub();
}
test();
这里会打印  66;
如果就书上所写的,是在函数调用时就创建作用域,当test()执行时,则会为test创建一个作用域链,但test内部又有一个sub函数,并且也执行了sub,即又为这个sub的环境里也创建了一个作用域链, sub的作用域在test执行环境里寻找到了s变量, 故打印了66.
销毁过程:
先销毁了sub(包括了 sub的作用域)
当test里面的变量没有被sub引用时,则接着销毁了test();
这是我目前的理解。

接着,我们将例子改一下。
function test() {
  var  s = 66;
      function sub() {

           alert(s);
      };
}
test();
这个例子与上面例子不同的时。 sub没有执行,则按照上面的理解。sub的作用域根本没有创建出来, 即这里只是声明了一个sub函数, test()执行完后,变量s与sub函数都会被销毁掉。
我们再将这个例子改一下
function test() {
  var  s = 66;
      setTimeout(function sub() {

           alert(s);
      },1000);
}
test();
这里还会1秒钟后打印66.  但sub是在1秒钟后才执行, 即在1秒后才建立作用域,但这里有个问题 ,test执行完后,应该检查到s变量没有被引用到时,则会被销毁掉,那一秒钟后 s 应该是undefined. 但这里为什么可以打印66呢?

所以讲到这里 ,可能是作用域并不是在函数调用时才创建的,应该是函数在创建时就创建了,即function a() {},就会由作用域,而不是等a()才有作用域,只有这样理解第三个例子才会讲得通。 但这个书也不应该写错啊, 所以这个疑问 ,希望有人能帮我回答 。谢谢。