为什么函数被调用? JavaScript / Window

时间:2015-09-25 18:15:56

标签: javascript

我的HTML文件中包含以下代码:

    <script type="text/javascript">
        window.never = function() {
                 console.log('this function is never called');
        }
        (function(d, s, id){
            var js, srjs = d.getElementsByTagName(s)[0];
            if (d.getElementById(id)) {return;}
            js = d.createElement(s); js.id = id;
            js.src = "this.script.does.not.exist.js";
            srjs.parentNode.insertBefore(js, srjs);
        }(document, 'script', 'streamrail-jssdk'));
    </script>

请参阅小提琴:http://jsfiddle.net/sebvaeja/

查看控制台,您可以看到实际调用了window.never函数('此函数永远不会被调用'写入控制台)。

使用Chrome开发工具调试时,我在调用堆栈中看到调用者是闭包(第一行:http://jsfiddle.net/sebvaeja/)。

如果我将never函数更改为全局范围:

    function never() {
             console.log('this function is never called');
    }

然后它没有被调用。

有人可以解释为什么是window.never函数被调用?什么是触发通话?我想这与窗口对象上的函数有关,但我看不出背后的原因。

2 个答案:

答案 0 :(得分:13)

函数表达式后跟括号:

 window.never = function() { ... }
 (...)

函数表达式后的换行符终止变量语句,因此对于函数调用的解析器:

function() { ... }(...)

事实上,你在这里使用的技术非常相似:

(function(d, s, id){
  // ...
}(document, 'script', 'streamrail-jssdk'))

这是一个函数表达式,后跟(...),它调用函数。

解决方案:在定义后添加分号,你就是好的。

  

如果我将never函数更改为全局范围......那么它就不会被调用。

在这种情况下,函数定义被解释为函数声明,而不是表达式。函数声明更像是一个语句,因此不能成为 CallExpression 的一部分。因此,以下括号被解释为分组运算符(如您所愿)。

答案 1 :(得分:5)

在函数声明后放置分号:

    window.never = function() {
             console.log('this function is never called');
    };

这是因为之后的(...)会触发函数调用。

    window.never = function() {
             console.log('this function is never called');
    }
    ( ... ) // <-- Triggers call of `window.never`