在 javascript 中的 return 语句之后执行的代码?

Code executing after return statement in javascript?

我在网上找到了这个简短的 JavaScript 片段:

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 在以前的代码版本中变成 return 1 吗?

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

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

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

这是由于hoisting

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

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

所以赋值前有个本地foo,你只覆盖本地。函数 foo() 也将消失。

这是因为代码转换为;

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

这是因为 JavaScript 总是将变量声明而不是初始化移到范围的顶部。

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 语句之后被调用,这是预期的.您现在的问题可能是 "Why is my console.log('1',foo) assigned to the function 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/