javascript 为什么返回后变量提升在某些浏览器上有效,而有些则不然?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3725546/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why variable hoisting after return works on some browsers, and some not?
提问by alter
alert(myVar1);
return false;
var myVar1;
Above code throws error in IE, FF and Opera stating that return statement has to come in the function. But it works (shows undefined) in Safari and Chrome.
上面的代码在 IE、FF 和 Opera 中抛出错误,说明函数中必须包含 return 语句。但它undefined在 Safari 和 Chrome 中工作(显示)。
The above code has been written in global scope. Outside all the functions.
上面的代码是在全局范围内编写的。在所有功能之外。
Any reason?
任何原因?
回答by AutomatedTester
In javaScript Variables are moved to the top of script and then run. So when you run it will do
在 javaScript 变量被移动到脚本的顶部然后运行。所以当你运行它会做
var myVar1;
alert(myVar1);
return false;
This is because javascript doesnt really have a true sense of lexical scoping. This is why its considered best practise to have all your variables declared at the top of the area they will be used to prevent hoisting causing a problem. JSLint will moan about this.
这是因为 javascript 并没有真正意义上的词法范围。这就是为什么将所有变量声明在它们将用于防止提升导致问题的区域的顶部被认为是最佳实践的原因。JSLint 会抱怨这个。
This is a good article that explains it http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
这是一篇解释它的好文章 http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting
The return is invalid. If you want to do a true hoisting example (taken from the link above) do
退货无效。如果您想做一个真正的提升示例(取自上面的链接),请执行
var foo = 1;
function bar() {
if (!foo) {
var foo = 10;
}
alert(foo);
}
bar();
This will alert 10
这将提醒 10
EDIT AFTER COMMENT
评论后编辑
Below is my understanding and I have read it somewhere but can't find all the sources that I read so am open to correction.
以下是我的理解,我已经在某处阅读过,但找不到我阅读的所有来源,因此可以更正。
This Alerts thanks to the differences in the JavaScript JIT. TraceMonkey(http://ejohn.org/blog/tracemonkey/) I believe will take the JavaScript and do a quick static analysis and then do JIT and then try run it. If that fails then obviously nothing works.
由于 JavaScript JIT 中的差异,此警报。TraceMonkey( http://ejohn.org/blog/tracemonkey/) 我相信会采用 JavaScript 并进行快速静态分析,然后进行 JIT,然后尝试运行它。如果失败,那么显然没有任何效果。
V8 doesnt do the static analysis and moves to the JIT then runs so something. Its more akin to python. If you run the script in the Developer console(ctrl+shift+j in windows) in Chrome it will throw an error but also run to give you the alert.
V8 不做静态分析并移动到 JIT 然后运行一些东西。它更类似于python。如果您在 Chrome 中的开发人员控制台(在 Windows 中为 ctrl+shift+j)中运行该脚本,它将引发错误,但也会运行以向您发出警报。
回答by alter
Sometimes hoisting is explained in a way which may give wrong impression, i.e. the variables and functions are hoisted by JavaScript engine as if they were physically moved on top, which is not actually right, as demonstrated by the code below:
有时以一种可能给人错误印象的方式解释提升,即变量和函数被 JavaScript 引擎提升,就好像它们被物理移动到顶部一样,这实际上是不正确的,如下面的代码所示:
console.log(a);
var a = 'Hello World!';
What we see on console is undefined, not 'Hello World', so we got the behavior of the following code
我们在控制台上看到的是undefined,不是'Hello World',所以我们得到了以下代码的行为
var a;
console.log(a);
a = 'Hello World!';
not the behavior of
不是行为
var a = 'Hello World!';
console.log(a);
which you may get the impression from the variables and functions declaration being moved to top statement.
您可能会从变量和函数声明移至 top 语句中获得印象。
But JavaScript is not actually moving your code anywhere. You need to understand execution context in JavaScript. It has two phases creation phase and execution phase. In creation phase memory space is created for these variables and functions, and people seem to confuse this step with hoisting. JavaScript is actually not moving your code anywhere, what happens is JavaScript has created memory space for all your code i.e. variables and functions, functions can be placed fully in memory but in case of variables the assignments are processed in execution phase of the execution context. So when you do var a = 'Hello World!', JavaScript engine knows the value of awhen it starts executing it in execution phase of execution context, so it puts a placeholder undefined, and all variables are initially set to undefined in JavaScript. So it is not good to rely on hoisting and see undefined. So it is always good to declare variables and functions on top of your code.
但是 JavaScript 实际上并没有将您的代码移动到任何地方。您需要了解 JavaScript 中的执行上下文。它有创建阶段和执行阶段两个阶段。在创建阶段为这些变量和函数创建了内存空间,人们似乎将这一步与提升混淆了。JavaScript 实际上并没有将您的代码移动到任何地方,发生的情况是 JavaScript 为您的所有代码(即变量和函数)创建了内存空间,函数可以完全放置在内存中,但在变量的情况下,分配在执行上下文的执行阶段进行处理。所以当你执行 var 时a = 'Hello World!',JavaScript 引擎知道a当它在执行上下文的执行阶段开始执行它时,它会放置一个未定义的占位符,并且所有变量在 JavaScript 中最初都设置为未定义。所以靠吊装看undefined是不好的。所以在你的代码之上声明变量和函数总是好的。
回答by strager
Section 12.9 (page 75) of ECMA-262 edition 3 states:
ECMA-262 第 3 版的第 12.9 节(第 75 页)指出:
An ECMAScript program is considered syntactically incorrect if it contains a
returnstatement that is not within a FunctionBody.
如果 ECMAScript 程序包含
return不在FunctionBody中的语句,则该程序被认为在语法上不正确。
That is, a returnoutside of a function is a syntax error. If a syntax erroroccurs, no code is run. Think about your example as if you had written:
也就是说,return函数的外部是语法错误。如果发生语法错误,则不会运行任何代码。想想你的例子,就像你写的一样:
alert(myVar1);
return false;
syntax error))))))))))))))))));
In addition, section 16 (page 157) states:
此外,第 16 节(第 157 页)指出:
An implementation may treat any instance of the following kinds of runtime errors as a syntax error and therefore report it early:
- Improper uses of return, break, and continue.
实现可以将以下类型的运行时错误的任何实例视为语法错误,因此及早报告:
- return、break 和 continue 的不当使用。
Firefox's engine et. al. (i.e. those JavaScript implementations which allow returnin the global scope) maybe conforming, assuming the following clause (in the same section) allows for implementation definition of returnin the global scope:
Firefox 的引擎等。阿尔。(即那些允许return在全局范围内的JavaScript 实现)可能是符合的,假设以下子句(在同一部分中)允许return在全局范围内的实现定义:
An implementation shall report all errors as specified, except for the following:
- An implementation may provide additional types, values, objects, properties, and functions beyond those described in this specification. This may cause constructs (such as looking up a variable in the global scope) to have implementation-defined behaviour instead of throwing an error (such as ReferenceError).
实现应报告指定的所有错误,但以下情况除外:
- 实现可以提供超出本规范中描述的其他类型、值、对象、属性和函数。这可能会导致构造(例如在全局范围内查找变量)具有实现定义的行为,而不是引发错误(例如ReferenceError)。
回答by marcgg
This code makes little sense:
这段代码没什么意义:
- The
var myVar1will never be ran. - The
return false;will not return a thing since you're not in a function
- 该
var myVar1永远不会跑去。 return false;由于您不在函数中,因此不会返回任何内容
Opera, IE and FF are right to throw an error because this code is really not valid since you're not able to return unless you are in a function.
Opera、IE 和 FF 抛出错误是正确的,因为此代码实际上无效,因为除非您在函数中,否则您无法返回。
If it works in Safari and Chrome it must be because the javascript engine they use is ready to handle buggy code. My guess would be that they see the "return" and drop or replace it with some kind of break.
如果它适用于 Safari 和 Chrome,那一定是因为它们使用的 javascript 引擎已准备好处理有缺陷的代码。我的猜测是他们看到了“ return”,然后将其删除或替换为某种break.
More information about functions: http://www.w3schools.com/js/js_functions.asp
关于函数的更多信息:http: //www.w3schools.com/js/js_functions.asp
回答by AugustRush
It is JavaScript Hoisting thing, Simply in other words, we are trying print the value of the variable , which is not holding any value
这是 JavaScript 提升的东西,简单地说,我们正在尝试打印变量的值,它不持有任何值
Javascript will render the above code as:-
Javascript 将上述代码呈现为:-
var myVar1
alert (myVar1)
return false
To clarify more i refered the link javascript hoisting: http://www.ufthelp.com/2014/11/JavaScript-Hoisting.html
为了澄清更多,我参考了javascript提升链接:http: //www.ufthelp.com/2014/11/JavaScript-Hoisting.html

