为什么不同浏览器对函数声明的处理方式不同?

IT技术 javascript firefox google-chrome
2021-02-22 08:39:59

虽然我无法在 google 中轻松找到对此的引用,但我熟悉这样一个事实,即在 javascript 中,全局函数声明在执行任何代码之前都会被解释。换句话说,这很好用:

f();
function f() {}

但是,我注意到 chrome 和 firefox 对全局函数声明的含义有不同的解释。特别是,chrome 很高兴在第一遍中读取 if 块内的函数声明,但 firefox 不是。

try {document.write(f);}               // works in chrome
catch(e) {document.write(e.message);}  // throws an error in firefox

try {document.write(g);}               // works in chrome and firefox
catch(e) {document.write(e.message);}

if(true) function f() {}
function g() {}

你可以用这个fiddle自己试试这个例子我使用的是 Chrome 16.0.912.75 和 Firefox 9.0.1。

这种行为的 ECMA 标准是什么?在其他代码之上“提升”函数声明的过程是否有术语?哪些代码被“解除”以供解释(两个浏览器都正确)?或者它是其中一个的错误?

2个回答

函数声明在块中无效你有未定义行为这是不确定的。

顶层(函数内的全局或顶层)的函数声明被提升。

块内的函数声明在严格模式下是语法错误

(function () { 
  "use strict"; 
  if (true) { 
    function g() { } 
  } 
})();

SyntaxError: In strict mode code, functions can only be declared at top level or immediately within another function.

我发现这是 JavaScript 的一个令人不安的限制——而且令人惊讶,因为函数是一流的对象。然后我意识到可以在块内声明函数,但它需要不同的语法:var g = function() {}
2021-04-21 08:39:59
@Chris 我不知道 Chrome 和 Firefox 以特定于实现的方式实现这种未定义行为的原因。但是它不能再被删除,因为这会破坏与互联网的向后兼容性
2021-04-23 08:39:59
实际上,规范在这里定义了行为:它被定义为一个 SyntaxError。这恰好与网络不兼容。
2021-04-25 08:39:59
谁知道?提交错误报告。
2021-05-03 08:39:59
好吧,那么为什么 Chrome 会如此愉快地吞下它们呢?
2021-05-04 08:39:59

此行为的 ECMA 标准是在解析脚本时抛出 SyntaxError。不幸的是,正如 Raynos 所说,这样做与网络不兼容。

请参阅根据标准哪个 JS 函数声明语法是正确的?对这个问题进行一些扩展讨论。

我记得,他们就此事达成了一致。不过我可能记错了。
2021-04-22 08:39:59