函数定义未提升

Viv*_*dra 5 javascript hoisting

Wrt提升fxn定义.

if (true) {
  function foo() {
    alert(1)
  }
} else {
  function foo() {
    alert(2)
  }
}
foo()
Run Code Online (Sandbox Code Playgroud)

Chrome,大约2-3个月前 - 将打印2.现在,它打印1.我错过了什么,或者控制台停止在fxn上升!

DEMO - 打印1.我不知道在哪里可以找到旧浏览器版本的演示.可能是老款v8引擎的节点安装?目前的镀铬版 - 49

str*_*str 8

您应该避免使用有条件创建的函数.

例如,假设以下代码:

if (false){
 function foo(){
  console.log(1)
 }
}
foo()
Run Code Online (Sandbox Code Playgroud)

Firefox不会提升功能,这将导致ReferenceError: foo is not defined.然而,Chrome仍然可以提升功能并进行打印1.所以显然你已经处理了不同的浏览器行为.因此,不要做那样的事情(或者如果你真的想使用函数表达式).

另请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function

函数可以有条件地声明,也就是说,函数语句可以嵌套在if语句中.除Mozilla之外的大多数浏览器都会将此类条件声明视为无条件声明,并在条件为真的情况下创建函数,请参阅此文章以获取概述.因此,不应使用它们,因为条件创建使用函数表达式.

特别要看一下链接的文章,它可以解释你所看到的问题.所以Chrome似乎在这方面有所改变.但同样,不要使用有条件创建的函数.

请注意,正如FREEZE所评论的那样,您应该使用'use strict';哪些不允许此类代码,而是抛出异常.


Ber*_*rgi 8

您拥有的代码在严格模式下无效.函数不会被块提升(或者至少它们不应该被提升),块内的函数声明在ES6之前是完全非法的.你应该写

"use strict";
var foo;
if (true) {
  foo = function() {
    alert(1)
  };
} else {
  foo = function() {
    alert(2)
  };
}
foo()
Run Code Online (Sandbox Code Playgroud)

以可重现和预期的结果获得所需的行为.

我错过了什么,或者控制台停止了fxn的升级!

看起来V8已更新以符合ES6规范.它确实将它们"提升"到函数/顶部作用域,但仅在实际遇到声明时(在您的情况下,有条件地).