13

我有一个应用程序在调试模式下编写在许多单独的 javascript 文件中,但作为页面头块的一部分同步加载。在发布时,我将所有这些文件合并在一起并缩小它们。今天我一直在缩小版本中发现一个错误,所以我加载了一个合并文件来调试问题,发现一个库正在自我执行一个函数,它导致其他定义的函数window被执行。

我已经用一个通用对象在这里 repo 了这个行为,不管它的窗口与否:

<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 

如果我将呼叫更改为

<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

这是我所期望的。在第一个示例中,为什么在传递给自执行函数X时被调用?a

4

3 回答 3

22

;将功能分配给 后,您会丢失a.X

触发分号插入。

匿名函数周围的 and 用于调用前一个函数,并将其返回值赋值(给。)X

即你所拥有的相当于:

var a = {};

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

顺便说一句,这个问题对JS Lint来说是一个很好的广告,它会选择它。

于 2013-08-22T19:51:35.360 回答
3

它与分号注入有关,因为当我输入分号时,它按预期工作:

    var a = {}

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

    (function(a){
        console.log("self execution");
    }(a));
于 2013-08-22T19:52:06.007 回答
1

;你在你之后错过了一个分号a.X = function x() { ...} ;

IE

a.X = function x(){
   console.log("shouldn't be executed");
};
于 2013-08-22T19:52:59.643 回答