2011-12-17 19 views
4

爲什麼下面的代碼無法在Internet Explorer(我只在IE8測試,到目前爲止)工作:如果我改變foo的分配如下在Internet Explorer中的Javascript有名函數表達式

(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 

,代碼工作得很好:

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

我想這是關於IE的Javascript引擎中的命名函數。該代碼在Chrome和Firefox中運行良好。

任何想法?

回答

8

IE對命名函數表達式有很多問題。正如你在提問時說,堅持這一點:

this.foo = function(){}; 

有關此主題的深入,艱苦的讀,看看this link

短的它是內在的,命名的函數表達式爲作爲功​​能處理聲明,並將其吊起到永遠不應該存在的地方。

+3

只是爲了增加更多的細節 - 有名函數表達式實際上在IE中創建兩個不同的對象。請參閱http://kangax.github.com/nfe/#jscript-bugs中的示例#3 – mikeycgto 2011-12-18 00:02:10

+0

因此,您不應該避免使用命名函數。作爲一個經驗法則,對待函數foo(){}的方式與var聲明相同,只有在之後將其分配給任何屬性。 – juandopazo 2011-12-18 00:33:24

+0

對於任何想出於代碼組織原因而使用NFE的人,但由於支持而無法使用NFE的人,一種解決方法是在功能名稱通常會去的地方使用函數名稱來滑動註釋。例如,'(function/* myFunctionName * /(){...}());'這可以很容易地在以後用真實的東西替換,並且幾乎可讀。 – 2014-12-22 21:57:11

5

在IE中,foo.prototype的用法是「ambigious」,因爲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" 
相關問題