简体   繁体   English

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

[英]Code executing after return statement in javascript?

I found this short JavaScript snippet in the web: 我在网上找到了这个简短的JavaScript代码段:

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

I would expect the contents after return statement in function bar() to be disregarded, and the variable foo to equal 10 at the end. 我希望可以忽略bar()函数中return语句之后的内容,并且变量foo的末尾等于10。 To my surprise however, the console outputs something very different: 但是令我惊讶的是,控制台输出的内容却大不相同:

1

Now, when I remove the line after return statement 现在,当我在return语句后删除行时

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

The console prints out, as expected: 控制台将按预期打印:

10

Can anyone explain me what causes foo to return 1 in the former version of the code? 谁能解释一下是什么原因导致foo在以前的代码版本中返回1?

Function declarations are hoisted to the top of their containing context. 函数声明被提升到其包含上下文的顶部。 You're essentially creating a var foo at the top of the bar function. 您实际上是在bar函数的顶部创建var foo

The foo manipulated in bar is local to that function and doesn't affect the global context's foo . bar操作的foo在该函数中是局部的,并且不影响全局上下文的foo

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

It is due to hoisting . 这是由于hoisting

Compiler will basically turn that into: 编译器基本上会将其转换为:

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

So there is a local foo before the assignment and you only overwrite the local. 因此,分配前有一个本地foo ,而您只覆盖了本地。 The function foo() would then also be gone. 然后,函数foo()也将消失。

tl;dr it's due to how function expressions and function declarations work (also, function hoisting): https://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/ tl; dr这是由于函数表达式和函数声明的工作方式(也称为函数提升): https : //javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/

More detailed response: 更详细的回复:

Putting the following console.log's in the code will help you visualize what is happening, and I think answer your question. 将以下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)

The output is as follows: 输出如下:

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

So to your suspicion, console.log('3',foo) and console.log('4',foo) never get called after the return statement, which was expected. 因此,令人怀疑的是,在返回语句之后,console.log('3',foo)和console.log('4',foo)从未被调用过,这是预期的。 Your question now is probably "Why is my console.log('1',foo) assigned to the function foo() {}", which can be answered with the following SO question which describes function declaration vs. function expressions, ie 您的问题现在可能是“为什么将我的console.log('1',foo)分配给函数foo(){}”,可以用以下描述函数声明与函数表达式的SO问题来回答,即

function foo(){}

vs

var foo = function(){}

Why can I use a function before it's defined in Javascript? 为什么在Javascript中定义函数之前就可以使用它?

Basically when bar is executed, the immediate definition of foo becomes function(){}, but the key concept here is this definition of foo is local to within the bar() function, and outside of bar 's scope it is still assigned to 1. 基本上,当执行bar时, foo的直接定义成为function(){},但是这里的关键概念是foo定义是在bar()函数内部的局部定义,并且在bar范围之外,它仍然被分配给1。

Another good read on function declarations and expressions: https://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/ 关于函数声明和表达式的另一本好书: https : //javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/

This is because the code is converted to; 这是因为代码被转换为;

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

This is because JavaScript always moves variable declarations and not initializations to the top of the scope. 这是因为JavaScript始终将变量声明而不是初始化移到范围的顶部。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM