函数定义未提升

时间:2016-11-18 12:47:52

标签: javascript hoisting

W.r.t吊装fxn定义。

if (true) {
  function foo() {
    alert(1)
  }
} else {
  function foo() {
    alert(2)
  }
}
foo()

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

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

2 个答案:

答案 0 :(得分:8)

您应该避免使用有条件创建的功能。

例如,假设以下代码:

if (false){
 function foo(){
  console.log(1)
 }
}
foo()

Firefox不会提升该功能,这将导致ReferenceError: foo is not defined。但是,Chrome会提升此功能并打印1。很明显,你已经处理不同的浏览器行为。因此,不要做那样的事情(或者如果你真的想使用函数表达式)。

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

  

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

特别要查看链接的文章,该文章在某种程度上解释了您所看到的问题。所以Chrome似乎在这方面有所改变。但同样,请不要使用有条件创建的函数。

请注意,正如FREEZE所评论的那样,您应该使用'use strict';,这将不允许此类代码,但会引发异常。

答案 1 :(得分:8)

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

"use strict";
var foo;
if (true) {
  foo = function() {
    alert(1)
  };
} else {
  foo = function() {
    alert(2)
  };
}
foo()

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

  

我是否错过了某些内容,或是控制台在fxn上停止了吊装!

看起来V8已更新为与the ES6 spec对齐。它确实将它们“提升”到函数/顶部范围,但仅在实际遇到声明时(在您的情况下,有条件地)。