35
alert(myVar1);
return false;
var myVar1;

上面的代码在 IE、FF 和 Opera 中抛出错误,指出函数中必须有 return 语句。但它undefined在 Safari 和 Chrome 中有效(显示)。

上面的代码是在全局范围内编写的。在所有功能之外。

任何原因?

4

5 回答 5

36

在 JavaScript 中,变量被移动到脚本的顶部,然后运行。所以当你运行它会做

var myVar1;
alert(myVar1);
return false;

这是因为 JavaScript 并没有真正意义上的词法作用域。这就是为什么将所有变量声明在将用于防止提升导致问题的区域的顶部被认为是最佳实践的原因。JSLint 会为此抱怨。

这是一篇很好的文章来解释它: http: //www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting

退货无效。如果您想做一个真正的吊装示例(取自上面的链接),请执行

var foo = 1; 
function bar() { 
    if (!foo) { 
        var foo = 10; 
    } 
    alert(foo); 
} 
bar();

这将提醒 10

以下是我的理解,我在某处读过,但找不到我读过的所有资料,因此愿意更正。

由于 JavaScript JIT 中的差异,此警报。TraceMonkey( http://ejohn.org/blog/tracemonkey/ ) 我相信会拿 JavaScript 做一个快速的静态分析,然后做 JIT,然后尝试运行它。如果失败了,那么显然没有任何效果。

V8 不进行静态分析并移动到 JIT 然后运行一些东西。它更类似于 Python。如果您在 Chrome 的开发人员控制台(Windows 中的 ctrl+shift+j)中运行脚本,它会抛出错误,但也会运行以向您发出警报。

于 2010-09-16T10:28:50.273 回答
18

有时对提升的解释可能会产生错误的印象,即变量和函数被 JavaScript 引擎提升,就好像它们被物理移动到顶部一样,这实际上是不正确的,如下面的代码所示:

console.log(a);
var a = 'Hello World!';

我们在控制台上看到的是undefined,不是'Hello World',所以我们得到了以下代码的行为

var a;
console.log(a);
a = 'Hello World!';

不是的行为

var a = 'Hello World!';
console.log(a);

您可能会从将变量和函数声明移到顶部语句中得到印象。

但是 JavaScript 实际上并没有将您的代码移动到任何地方。您需要了解 JavaScript 中的执行上下文。它有创建阶段和执行阶段两个阶段。在创建阶段,为这些变量和函数创建了内存空间,人们似乎将此步骤与提升混淆了。JavaScript 实际上并没有将您的代码移动到任何地方,发生的情况是 JavaScript 为您的所有代码(即变量和函数)创建了内存空间,函数可以完全放置在内存中,但如果是变量,则在执行上下文的执行阶段处理分配。所以当你做 var 时a = 'Hello World!',JavaScript 引擎知道a当它在执行上下文的执行阶段开始执行它时,它会放置一个未定义的占位符,并且所有变量最初在 JavaScript 中都设置为未定义。所以靠吊装看未定义是不好的。因此,在代码之上声明变量和函数总是好的。

于 2015-09-09T09:32:50.627 回答
12

ECMA-262 第 3 版的第 12.9 节(第 75 页)指出:

如果 ECMAScript 程序包含return不在FunctionBody中的语句,则认为它在语法上不正确。

也就是说,return函数的外部是语法错误。如果发生语法错误,则不会运行任何代码。想想你的例子,就好像你写过:

alert(myVar1);
return false;
syntax error))))))))))))))))));

此外,第 16 条(第 157 页)规定:

实现可以将以下类型的运行时错误的任何实例视为语法错误,因此会提前报告:

  • return、break 和 continue 的不当使用。

Firefox 的引擎等。人。(即那些允许return在全局范围内的 JavaScript 实现)可能是一致的,假设以下子句(在同一部分中)允许return在全局范围内定义实现:

实现应按规定报告所有错误,但以下情况除外:

  • 实现可以提供超出本规范中描述的其他类型、值、对象、属性和功能。这可能会导致构造(例如在全局范围内查找变量)具有实现定义的行为,而不是引发错误(例如ReferenceError)。
于 2010-09-16T16:57:46.787 回答
3

这段代码意义不大:

  • var myVar1永远不会运行。
  • return false;由于您不在函数中,因此不会返回任何东西

Opera、IE 和 FF 抛出错误是正确的,因为此代码实际上是无效的,因为除非您在函数中,否则您无法返回。

如果它在 Safari 和 Chrome 中工作,那一定是因为他们使用的 javascript 引擎已经准备好处理错误代码。我的猜测是他们看到了“ return”,然后将其删除或替换为某种break.

有关函数的更多信息:http: //www.w3schools.com/js/js_functions.asp

于 2010-09-16T10:06:30.667 回答
0

这是 JavaScript 提升的东西,换句话说,我们正在尝试打印变量的值,它没有保存任何值

Javascript 会将上述代码呈现为:-

var myVar1
alert (myVar1)
return false

为了澄清更多,我参考了链接javascript提升: http ://www.ufthelp.com/2014/11/JavaScript-Hoisting.html

于 2014-11-16T13:03:12.927 回答