【问题标题】:Code executing after return statement in javascript?在javascript中的return语句之后执行的代码?
【发布时间】:2017-04-25 17:52:38
【问题描述】:

我在网上找到了这个简短的 JavaScript sn-p:

var foo = 1;
function bar() {
    foo = 10;
    return;
    function foo() {}
}
bar();
console.log(foo);

我希望函数 bar() 中的 return 语句之后的内容被忽略,并且变量 foo 最后等于 10。然而令我惊讶的是,控制台输出了一些非常不同的东西:

1

现在,当我删除 return 语句后的行时

var foo = 1;
function bar() {
    foo = 10;
    return;
}
bar();
console.log(foo);

控制台按预期打印出来:

10

谁能解释一下是什么原因导致 foo 在之前版本的代码中返回 1?

【问题讨论】:

    标签: javascript return evaluation


    【解决方案1】:

    函数声明被提升到其包含上下文的顶部。您实际上是在 bar 函数的顶部创建了一个 var foo

    bar 中操作的foo 是该函数的本地函数,不会影响全局上下文的foo

    http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

    【讨论】:

      【解决方案2】:

      tl;dr 这是由于函数表达式和函数声明的工作方式(还有函数提升):https://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/

      更详细的回复:

      将以下 console.log 放入代码中将帮助您直观地了解正在发生的事情,我想回答您的问题。

      var foo = 1;
      console.log('0', foo)
      function bar() {
          console.log('1', foo)
          foo = 10;
          console.log('2', foo)
          return;
          console.log('3', foo)
          function foo() {}
          console.log('4', foo)
      }
      console.log('5', foo)
      bar();
      console.log('6', foo)
      

      输出如下:

      '0' 1
      '5' 1
      '1' function foo() {}
      '2' 10
      '6' 1
      

      所以你怀疑,console.log('3',foo) 和 console.log('4',foo) 在 return 语句之后永远不会被调用,这是预期的。您现在的问题可能是“为什么我的 console.log('1',foo) 分配给函数 foo() {}”,可以通过以下描述函数声明与函数表达式的 SO 问题来回答,即

      function foo(){}
      

      var foo = function(){}
      

      Why can I use a function before it's defined in Javascript?

      基本上在执行bar 时,foo 的直接定义变为 function(){},但这里的关键概念是 foo 的此定义是局部于 bar() 函数内部的,而在外部bar 的作用域仍然分配给 1。

      另一个关于函数声明和表达式的好读物:https://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/

      【讨论】:

      • 我接受了这个作为正确答案,因为它是最全面的。谢谢!
      • @MarcinWasilewski 我会改写它是最长的。
      【解决方案3】:

      这是由于hoisting

      编译器基本上会把它变成:

      function bar() {
          function foo() {}
          foo = 10;
          return;       
      }
      

      所以在分配之前有一个本地foo,你只覆盖本地。然后函数foo() 也将消失。

      【讨论】:

        【解决方案4】:

        这是因为代码转换为;

        var foo = 1;
        function bar() {
            var foo;
            foo = 10;
            return;
            function foo() {}
        }
        bar();
        console.log(foo);
        

        这是因为 JavaScript 总是将变量声明而不是初始化移动到作用域的顶部。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-09-24
          • 1970-01-01
          • 2023-03-04
          • 2021-01-16
          • 2023-02-07
          • 1970-01-01
          • 2012-02-04
          • 1970-01-01
          相关资源
          最近更新 更多