js一个关于作用域和执行环境的例子

在网上无意中看到一个关于js的作用域和执行环境的面试题,以前我也没怎么总是这些东西,经过一小段时间的研究,我慢慢开始明白其中的奥妙,这对以后写程序还是大有帮助的。日志代码如下:

f = function() {return true;}; 
g = function() {return false;}; 
(function() { 
   if (g() && [] == ![]) { 
      f = function f() {return false;}; 
      function g() {return true;} 
   } 
})(); 
alert(f()); // true or false ?

可能大家一开始看到这个题目肯定都和我一样猜到了,最后输出的是false。那分析一下怎么得出结论的吧。


首先给大家脑补一下([] == ![])得到的应该是true。其中的缘由的家慢慢去领会吧。然后用这个例子给大家普及一点作用域链的知识。

在这段js代码执行下来的时候,会形成一条作用域链(我习惯把作用域链分层,可能这样不科学,但是有助于我们理解),在作用域链(第一层作用域链)的外层就是第1,2,9,还有整个3-8行的代码,在3-8行的代码内部又衍生出一条新的作用域链(第二层作用域链),在3-8行的内部,匿名函数function和它内部就是第二层作用域链。每一层都会有个执行环境,在下一层的执行环境里边可以访问上一层(或者更外层)执行环境中的变量,但是在上层执行环境中不能访问下一层执行环境中的私有变量(解决这个问题就要用闭包的思想)。


执行的第一阶段:在这个例子中的4行的if判断中执行的g()函数其实首先会在if所在当前层找有没有这个函数,如果没有,然后再顺着作用域链向上层寻找,因此首先会执行第6行的g()函数,返回true,因此,第一阶段的if判断为什么会返回true的疑惑就解决了。

执行的第二阶段:接下来就要执行if判断内部的代码了,在代码的第5行对前边的f()函数进行了重写(在f前边没有加var,因此就是覆盖全局的f变量),因此在内存中原本保存的f()函数就变了,应该返回false了,因此,内存中的f()改变,最后在第一层作用域中alert(f())就返回false。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章