Javascript:将命名函数分配给变量时不一致(命名函数表达式)

时间:2013-02-06 15:02:14

标签: javascript internet-explorer firefox cross-browser

任何人都可以解释Internet Explorer和Firefox之间在以下方面的行为差异:

var myNamespace = (function () {
  var exposed = {};

  exposed.myFunction = function myFunction () {
    return "Works!";
  }

  console.log(myFunction()); 
  // IE: "Works!"
  // Firefox: ReferenceError: myFunction is not defined

  console.log(exposed.myFunction());
  // IE: "Works!"
  // FF: "Works!"

  return exposed;
})();

console.log(myNamespace.myFunction()); 
// IE: "Works!"
// FF: "Works!"

在Internet Explorer中,此方法允许我使用myFunction()exposed.myFunction()从命名空间函数内部调用我的函数。

在我的名字功能之外,我可以使用myNamespace.myFunction()

在Firefox中,结果是相同的,除了没有用的裸命名函数调用。

它应该有用吗?如果不应该,那为什么不呢?

如果它应该是一个已知的错误?

3 个答案:

答案 0 :(得分:6)

防止虚假信息:

IE有命名函数表达式的问题,这就是你所拥有的。该功能的名称只能在内部功能中使用。来自specification

  

FunctionExpression 中的标识符可以从 FunctionExpression FunctionBody 中引用,以允许该功能以递归方式称呼自己。但是,与 FunctionDeclaration 不同, FunctionExpression 中的标识符无法引用,也不会影响包含 FunctionExpression <的范围/ em>的

其中 FunctionExpression 定义为:

  

FunctionExpression
  function 标识符 opt ( FormalParameterList opt { FunctionBody }

但是在IE中,它不是仅在函数内部使用该名称,而是创建两个不同的函数对象,一个分配给变量,另一个分配给您给函数的名称。以下将在IE中产生false(并在其他浏览器中抛出错误):

exposed.myFunction === myFunction;

这是一个已知的错误,如果你必须为IE的旧版本编写代码,最好避免使用命名函数表达式。


相关问题:

答案 1 :(得分:2)

此:

exposed.myFunction = function myFunction () {
    return "Works!";
}

没用( - 纠正自己:这不是错误的 - )并且显然是错误的(见Felix的帖子)。如果您希望声明exposed的函数部分,则无需为其命名:

exposed.myFunction = function() {
    return "Works!";
}

但是,如果您想声明一个本地函数然后也会影响它对您的数组exposed,您可以这样做:

function myFunction () {
    return "Works!";
}

exposed.myFunction = myFunction;
在这种情况下,

会成功验证(exposed.myFunction === myFunction) === true;

此外,请注意,您对console.log(myNamespace.myFunction());的来电与对console.log(exposed.myFunction());的来电相同,因为myNamespace实际上是对象exposed

答案 2 :(得分:0)

另外,通过定义

exposed.myFunction = function() {}

您将exposed属性设置为myFunction

它在myNamespace范围内不可用。

通过定义

exposed.myFunction = function myFunction() {}

该函数在myNamespace范围内创建,然后作为exposed的属性引用。