Javascript 为什么返回后的变量在某些浏览器上有效,而在某些浏览器上无效?

Javascript 为什么返回后的变量在某些浏览器上有效,而在某些浏览器上无效?,javascript,hoisting,Javascript,Hoisting,上面的代码在IE、FF和Opera中抛出错误,指出返回语句必须出现在函数中。但是它在Safari和Chrome中工作(显示未定义的) 以上代码是在全局范围内编写的。在所有功能之外 有什么原因吗?这段代码没有什么意义: 将永远不会运行var myVar1 返回false不会返回任何内容,因为您不在函数中 Opera、IE和FF抛出错误是正确的,因为此代码实际上无效,因为除非您在函数中,否则无法返回 如果它能在Safari和Chrome中工作,那一定是因为他们使用的javascript引擎已经准

上面的代码在IE、FF和Opera中抛出错误,指出返回语句必须出现在函数中。但是它在Safari和Chrome中工作(显示
未定义的

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


有什么原因吗?

这段代码没有什么意义:

  • 将永远不会运行
    var myVar1
  • 返回false不会返回任何内容,因为您不在函数中
Opera、IE和FF抛出错误是正确的,因为此代码实际上无效,因为除非您在函数中,否则无法返回

如果它能在Safari和Chrome中工作,那一定是因为他们使用的javascript引擎已经准备好处理错误代码了。我猜他们会看到“
返回”
”并将其删除或替换为某种类型的
中断


有关函数的更多信息:

在JavaScript中,变量被移动到脚本顶部,然后运行。所以当你跑步的时候就可以了

alert(myVar1);
return false;
var myVar1;
这是因为JavaScript并没有真正意义上的词法范围。这就是为什么将所有变量声明在区域顶部被认为是最佳实践的原因,这些变量将用于防止吊装引起问题。杰斯林特会为此抱怨的

这篇文章很好地解释了这一点:

报税表无效。如果你想做一个真正的提升例子(取自上面的链接),那么

这将提醒10

下面是我的理解,我在某个地方读过,但找不到我读过的所有来源,所以我愿意更正

这是由于JavaScript JIT中的差异而发出的警报。我相信TraceMonkey()将使用JavaScript进行快速静态分析,然后进行JIT,然后尝试运行它。如果失败了,那么显然什么都不起作用

V8不做静态分析,而是转到JIT,然后运行,所以有些东西。它更类似于Python。如果您在Chrome的开发者控制台(Windows中的ctrl+shift+j)中运行脚本,它将抛出一个错误,但也会运行以向您发出警报。

ECMA-262第3版第12.9节(第75页)规定:

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

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

var foo = 1; 
function bar() { 
    if (!foo) { 
        var foo = 10; 
    } 
    alert(foo); 
} 
bar();
此外,第16节(第157页)规定:

一个实现可以将以下类型的运行时错误的任何实例视为语法错误,因此 尽早报告:

  • 返回、中断和继续的不当使用
Firefox的引擎等(即那些在全局范围内允许
返回
的JavaScript实现)可能是一致的,假设以下条款(在同一节中)允许在全局范围内定义
返回

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

  • 除了本规范中描述的类型、值、对象、属性和函数之外,实现还可以提供其他类型、值、对象、属性和函数。这可能会导致构造(例如在全局范围中查找变量)具有实现定义的行为,而不是抛出错误(例如ReferenceError

这是一件非常重要的事情,简单地说,我们正在尝试打印变量的值,它不包含任何值

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

var myVar1
警报(myVar1)

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

alert(myVar1);
return false;
syntax error))))))))))))))))));
我们在控制台上看到的是
未定义的
,而不是
“Hello World”
,因此我们得到了以下代码的行为

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

var a;
console.log(a);
a = 'Hello World!';
您可能会从移至top语句的变量和函数声明中得到印象


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

我感到害怕、困惑和有点好奇。。。你想帮凶什么?@Hahsen,我只是想了解各种可用的浏览器和javascript陷阱。这是一个变量提升,我试图理解它在全局范围内的行为以及返回语句。虽然不在函数定义中时不允许返回,但代码仍在chrome和safari中工作。我试图找出原因,将其理解为变量和声明预处理可能更容易。声明不会被移动(或“提升到顶部”),而是在执行任何代码之前进行处理。阅读ECMA-262§10.3,了解进入执行公司时发生的情况
var a;
console.log(a);
a = 'Hello World!';
var a = 'Hello World!';
console.log(a);