为什么返回后变量提升在某些浏览器上有效,而有些则不然?

IT技术 javascript hoisting
2021-01-27 13:28:31
alert(myVar1);
return false;
var myVar1;

上面的代码在 IE、FF 和 Opera 中抛出错误,说明函数中必须包含 return 语句。但它undefined在 Safari 和 Chrome 中工作(显示)。

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

任何原因?

5个回答

在 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)中运行该脚本,它将抛出错误,但也会运行以向您发出警报。

@Automater Tester,您的代码完全正确,它是在 javascript 中提升的一个非常好的示例。但我想知道的是,为什么 return 没有在 chrome 和 safari 中抛出错误
2021-03-21 13:28:31
@alter 我为您添加了更多信息。
2021-03-23 13:28:31
“在 javaScript 中,变量被移动到脚本的顶部,然后运行。” 实际上,变量名称(而不是分配/定义)“悬挂”于包含范围内的顶部(取最接近的; if。等人做的。创建在这个意义上的“范围”)。
2021-03-27 13:28:31
@strager 你是对的,只挂了名字。当我输入“然后运行”时,我指的是整个脚本。
2021-03-28 13:28:31
小心使用新的 ES6 JavaScript 特性。用 const/let 声明的变量不再被提升(是的,这个语句有点简化)。详细解释:stackoverflow.com/q/31219420/3242070
2021-04-10 13:28:31

有时以一种可能给人错误印象的方式解释提升,即变量和函数被 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);

您可能会从变量和函数声明移至 top 语句中获得印象。

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

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)。

这段代码没什么意义:

  • var myVar1永远不会跑去。
  • return false;由于您不在函数中因此不会返回任何内容

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

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

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

当我在函数之外使用return语句时,Chrome 会出错
2021-03-13 13:28:31
不管没有函数就不允许 return 语句这一事实,提升应该发生在这里,我应该得到一个警告,说未定义。当我有一个 return 语句时,我没有看到这种情况发生。
2021-03-17 13:28:31

这是 JavaScript 提升的东西,简单地说,我们正在尝试打印变量的值,它不持有任何值

Javascript 将上述代码呈现为:-

var myVar1
alert (myVar1)
return false

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