2013-08-22 28 views
13

我有一個應用程序,在調試模式下寫入許多單獨的JavaScript文件,但作爲頁面的頭塊的一部分同步加載。在發行版中,我將所有這些文件合併在一起並將它們縮小。今天,我一直在縮小版本中發現一個錯誤,所以我加載了一個合併文件來調試問題,發現一個庫自我執行一個函數,並導致在window上定義的其他函數被執行。爲什麼從一個自動執行的函數中執行該對象上的函數?

<head> 
    <script> 
     var a = {} 

     a.X = function x(){ 
      console.log("shouldn't be executed"); 
     } 

     (function(a){ 
      console.log("self execution"); 
     }(a)); 
    </script> 
</head> 

在這個例子中,我得到的

self execution 
shouldn't be executed 
輸出:

我repo'd的行爲在這裏與一個通用對象不一樣,如果它的窗口或沒有關係

如果我改變呼叫被

<head> 
    <script> 
     var a = {} 

     function x(){ 
      console.log("shouldn't be executed"); 
     } 

     a.X = x; 

     (function(a){ 
      console.log("self execution"); 
     }(a)); 
    </script> 
</head> 

然後我得到

self execution 

這是我的預期。在第一個例子中,當a傳遞給自執行函數時,爲什麼X被調用?

+0

我很疑惑爲什麼這樣的問題會在很短的時間內得到很多upvotes ...是因爲它被標記使用Javascript,並且具有不立即顯而易見的行爲...? – Lekensteyn

+10

生活證明,你應該插入分號= D – Esailija

+0

是的,有時候這些半決賽是很重要的,我們可以看到他們在做什麼和失蹤的時候可以如何模糊!經驗教訓:總是使用半決賽。 – dandavis

回答

22

將功能分配給a.X後,您缺少;

分號插入是而不是觸發。

圍繞匿名函數的()用於調用上一個函數,並將其返回值分配給X

即你有什麼等價於:

var a = {}; 

a.X = (function x(){ 
    console.log("shouldn't be executed"); 
}(
    (function(a){ 
     console.log("self execution"); 
    }(a)) 
)); 

順便說一句,這個問題是JS Lint一個很好的廣告,這將有把它撿起來。

+2

LOL我剛纔注意到了。這就是爲什麼你應該使用**分號! – Neal

+0

@asawyer - 思考我輸入的內容太遠,修正。 – Quentin

+0

哈,真棒。謝謝。同樣這也很有意義,爲什麼當我加載多個文件時,它們沒有機會以這種方式執行對方。當我將所有內容合併成一個文件時,突然間出現分號。 – devshorts

3

它有事情做與分號注入,因爲當我把分號它按預期工作:

var a = {} 

    a.X = function x(){ 
     console.log("shouldn't be executed"); 
    }; // added semicolon 

    (function(a){ 
     console.log("self execution"); 
    }(a)); 
1

後您a.X = function x() { ...} ;

a.X = function x(){ 
    console.log("shouldn't be executed"); 
}; 
你已經錯過了一個分號 ;