请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

为什么在执行2-3中的最后一个例子的时候执行出来的结果并不是3而是2

 function foo() {

            console.log(a); // 3  (不是 2!)

        }


        function bar() {

            var a = 3;

            foo();

        }


        var a = 2;


        bar();



https://img1.sycdn.imooc.com/szimg/5dc0eadd09d13ef804000048.jpg

正在回答

4回答

快乐动起来呀 2019-11-07 00:41:24

这块的材料有问题,我研究下出处和词法作用域,稍后更正,多谢反馈哈

1 回复 有任何疑惑可以回复我~
2014不可思议 2019-11-28 16:14:44

这里我的理解是,foo是全局声明的函数,引擎执行时如果在foo内部作用域找不到变量,会去全局找。可以参考下面两段代码,就不难理解了~//img1.sycdn.imooc.com//szimg/5ddf81a309b9477704330197.jpghttps://img1.sycdn.imooc.com//szimg/5ddf835409cbd04703040168.jpg

1 回复 有任何疑惑可以回复我~
时光拿铁 2019-11-25 12:38:39

个人理解:

    JS的解析过程分为两个阶段:预编译期(预处理、预解析、预编译)与执行期。

       第一步:找一些东西.(代码还没有执行。预览页面之前,写完之后)
       找程序中var关键字,如果找到了提前给var定义的变量赋值undefined
       找程序中的普通函数,如果找到了,函数提升,将整个函数赋值给函数名。
       如果找的var的名字和函数名字相同,函数优先。
       
       第二步: 逐行解析代码。按照上下顺序。如果碰到函数定义,忽略。
       重点:函数内部同样适用于js预解析。

第一步:预解析
function foo(){
    console.log(a)
}
function bar(){
    var a = undefined
    foo()
}

var a = undefined
bar()

第二步逐行解析代码
function foo(){
  console.log(a) (解析第五步),此刻a=2(全局变量)
}
function bar(){
  var a = 3 (解析第三步)
  foo() (解析第四步)
}
var a = 2 (解析第一步)
bar() (解析第二步)
 


1 回复 有任何疑惑可以回复我~
  • 提问者 栾树 #1
    谢谢,我觉得这个应该执行执行上下栈来解释会不会更清楚一些,我看的有点懵
    回复 有任何疑惑可以回复我~ 2019-12-04 11:05:06
可乐小猫 2019-12-04 10:35:53

取自课外阅读 第二篇 JavaScript深入之词法作用域和动态作用域

var value = 1;
function foo() {
    console.log(value);
}
function bar() {
    var value = 2;    
    foo();
}
bar();
// 结果是 ???

假设JavaScript采用静态作用域,让我们分析下执行过程:

执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。

假设JavaScript采用动态作用域,让我们分析下执行过程:

执行 foo 函数,依然是从 foo 函数内部查找是否有局部变量 value。如果没有,就从调用函数的作用域,也就是 bar 函数内部查找 value 变量,所以结果会打印 2。

前面我们已经说了,JavaScript采用的是静态作用域,所以这个例子的结果是 1。


0 回复 有任何疑惑可以回复我~
  • 提问者 栾树 #1
    谢谢,我查的资料也是这样的,我一开始用作用域链去理解这个但是我把作用域链中的父级的概念搞错了
    回复 有任何疑惑可以回复我~ 2019-12-04 11:02:10
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信