在Internet Explorer中,Javascript命名函数表达式

4
为什么以下代码在Internet Explorer中不能正常工作(我只测试了IE8):

```

(function(){
  this.foo = function foo(){};

  foo.prototype = {
    bar:function(){
      return 'bar';
    }
  };
})();

var x = new foo;
console.log(x.bar()) // Error: Object doesn't support this property or method

如果我将foo的赋值更改为以下内容,则代码可以正常工作:
var foo = this.foo = function(){};

我想这可能与IE的JavaScript引擎中的命名函数有关。该代码在Chrome和Firefox中工作正常。
有任何想法吗?
2个回答

8

IE在命名函数表达式方面存在很多问题。正如您在问题中所说的那样,请坚持使用以下内容:

this.foo = function (){};

如果你想深入了解这个话题,不妨查看这个链接

简单来说,内部的命名函数表达式被视为一个函数声明,并被提升到它绝对不应该出现的位置。


3
补充一些细节--在IE中,具名函数表达式实际上会创建两个不同的对象。请参见http://kangax.github.com/nfe/#jscript-bugs中的第3个示例。 - mikeycgto
你不应该因为这个原因而避免使用命名函数。作为一个经验法则,对待函数foo(){}的方式应该和你对待变量声明一样,在之后再将其分配给任何属性。 - juandopazo
想要使用NFE(命名函数表达式)来进行代码组织,但因为兼容性无法实现的各位,有一个解决方法是在通常函数名应该出现的位置上滑入带有函数名的注释。例如:(function /* myFunctionName */ () {...}()); 这样可以方便地在以后替换成真正的函数,并且几乎和真正的函数一样易读。 - Chris Middleton
1
看起来这个好像自2014年和IE8以后就没有更新过了。IE10和IE11如何处理命名函数表达式? - Daniel Bingham

5
在IE浏览器中,foo.prototype的使用是“模糊的”,因为NFE标识符泄漏到包含范围。 由于局部泄漏的foo比全局foo更接近,foo.prototype将增强局部的foo而不是window.foo
当您离开外部函数时,局部的foo会丢失,并且全局的foo由于上述原因没有.prototype.bar
您可以通过以下方式解决歧义:
(function(){
  this.foo = function foo(){};

  this.foo.prototype = {
    bar:function(){
      return 'bar';
    }
  };
})();

var x = new foo;
console.log(x.bar()) //"bar"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接