简体   繁体   English

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

[英]Javascript: Inconsistency when assigning a named function to a variable (named function expression)

Can anyone explain the difference in behaviour between Internet Explorer and Firefox in regards to the below: 任何人都可以解释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!"

In internet explorer this method allows me to call my function from inside my namespace function by using either myFunction() or exposed.myFunction() . 在Internet Explorer中,这个方法允许我通过使用myFunction()exposed.myFunction()从我的命名空间函数内部调用我的函数。

Outside my namepsace function I can use myNamespace.myFunction() 在我的namepsace函数之外,我可以使用myNamespace.myFunction()

In Firefox, the results are the same with the exception of the bare named function call which does not work. 在Firefox中,结果是相同的,除了没有用的裸命名函数调用。

Should it work? 应该有用吗? If it shouldn't, then why not? 如果不应该,那么为什么不呢?

If it should then is this a known bug? 如果它应该是一个已知的错误?

To prevent false information: 为防止虚假信息:

IE has a problem with named function expressions which is what you have. IE有一个命名函数表达式的问题,这就是你所拥有的。 The name of the function should only be available inside the function. 该函数的名称只能在函数内部使用。 From the specification : 规格

The Identifier in a FunctionExpression can be referenced from inside the FunctionExpression 's FunctionBody to allow the function to call itself recursively. 可以从FunctionExpressionFunctionBody内部引用FunctionExpression中标识符 ,以允许函数递归调用自身。 However, unlike in a FunctionDeclaration , the Identifier in a FunctionExpression cannot be referenced from and does not affect the scope enclosing the FunctionExpression . 然而,与在FunctionDeclaration,FunctionExpression 标识符无法从引用,不影响封闭FunctionExpression范围。

where FunctionExpression is defined as: 其中FunctionExpression定义为:

FunctionExpression : FunctionExpression
function Identifier opt ( FormalParameterList opt ) { FunctionBody } function Identifier opt ( FormalParameterList opt{ FunctionBody }

But in IE, instead of making the name only available inside the function, it creates two different function objects, one assigned to the variable and the other to the name you gave the function. 但是在IE中,它不是使名称仅在函数内部可用,而是创建两个不同的函数对象,一个分配给变量,另一个分配给您给函数的名称。 The following will yield false in IE (and throw an error in other browsers): 以下将在IE中产生false (并在其他浏览器中抛出错误):

exposed.myFunction === myFunction;

It's a known bug and if you have to code for (older versions of) IE, you better avoid named function expressions. 这是一个已知的错误,如果你必须为IE的旧版本编写代码,你最好避免使用命名函数表达式。


Related question: 相关问题:

This: 这个:

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

is useless (- correcting myself: it is NOT incorrect - ) and apparently buggy (see Felix's post). 是无用的(纠正自己:这不是错误的 - )并且显然是错误的(参见Felix的帖子)。 If you wish to declare a function part of exposed you don't need to name it: 如果您希望声明exposed的函数部分,则无需为其命名:

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

However, if you want to declare a local function and then also affect it to your array exposed , you can do: 但是,如果要声明本地函数,然后还要将其影响到exposed的数组,则可以执行以下操作:

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

exposed.myFunction = myFunction;

which would, in this case, successfully validate (exposed.myFunction === myFunction) === true; 在这种情况下,成功验证(exposed.myFunction === myFunction) === true;

Also, please note that your call to console.log(myNamespace.myFunction()); 另外,请注意您对console.log(myNamespace.myFunction());的调用console.log(myNamespace.myFunction()); is identical to your call to console.log(exposed.myFunction()); 与调用console.log(exposed.myFunction()); since myNamespace is actually the object exposed . 因为myNamespace实际上是exposed的对象。

Also, By defining 另外,通过定义

exposed.myFunction = function() {}

You are setting exposed 's property to be myFunction . 您将exposed属性设置为myFunction

And it is not available in the myNamespace scope. 它在myNamespace范围内不可用。

By defining 通过定义

exposed.myFunction = function myFunction() {}

The function is created in the scope of myNamespace , and then referenced as a property of exposed . 该函数在myNamespace的范围内myNamespace ,然后作为exposed属性引用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM