我在这里很困惑。有人可以帮我剥离功能定义中的图层吗?最多的括号是什么?为什么参数(p)可以在} 之后,它的功能是什么?根本需要 q 在哪里?为什么 p 可以在以后直接调用publish()?
var p = {};
(function(q) {
q.publish = function(topic, data){
...
};
}(p));
...
p.publish("inbox", "hello");
答案 0 :(得分:1)
它只是创建函数并立即执行它。
例如:
var foo = function() {
return 5;
}();
console.log(foo);
将打印5
。
如果您想了解更多相关信息,请阅读这篇优秀文章http://benalman.com/news/2010/11/immediately-invoked-function-expression/
我想从我分享的链接中引用模块模式示例。
var counter = (function(){
var i = 0;
return {
get: function(){
return i;
},
set: function( val ){
i = val;
},
increment: function() {
return ++i;
}
};
}());
console.log(counter.get());
counter.set(3);
console.log(counter.increment());
console.log(counter.i);
<强>输出强>
0
4
undefined
这里我们在i
私有的同时动态创建一个Object。这称为封闭属性。
答案 1 :(得分:0)
这是一个自我执行的功能。由于q
,因此使用q === p
无效。
var p = 'hello';
function f(q){ return q; }; f(p); // "hello"
(function(q){ return q; }(p)); // "hello"
(function(){ return p; }()); // "hello"
/*(*/function(){ return p; }()/*)*/; // SyntaxError: Unexpected token (
此模式通常用于为变量创建私有上下文。这是一个众所周知的例子:
var counter = function(){
var i = 0;
return function(){
return ++i;
};
}();
counter(); // 1
counter(); // 2
i; // undefined
看看这篇好文章:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html。
答案 2 :(得分:0)
将函数放在括号中意味着JS解释器将其作为函数表达式,因此它可以是匿名的(即,没有声明的名称)。在末尾添加()
意味着立即调用该函数。所以,例如:
(function() {
alert('Hi');
}());
...声明一个没有参数的非常简单的函数,并立即调用它。带参数的稍微复杂一点可能如下所示:
(function(someArgument) {
alert(someArgument);
}('Hi'));
这会警告'Hi',因为字符串'Hi'
在被调用时会被传递给匿名函数。
因此,以此为背景,这是您的代码逐行执行的操作:
var p = {}; // declare variable p, referencing an empty object
(function(q) { // make an anonymous function expression that takes one argument, q
q.publish = function(topic, data){ // add a property 'publish' to whatever q is,
... // where 'publish' is a function that takes
}; // two arguments
}(p)); // call the anonymous function, passing p in
...
p.publish("inbox", "hello"); // call the method 'publish' that was added to p
您询问的q
参数从p
获取值,因此它引用相同的空对象,但随后它将.publish()
方法添加到该对象。
这个一般概念称为“Immediated invoked function expression”,或IIFE。
通常,如果一个IIFE就像那样独自坐在那里(也就是说,另一个变量没有分配给它),那么就可以暂时创建工作变量/函数而不将它们添加到全局范围,因为JavaScript范围选项基本上是全局或功能。您显示的代码不会这样做,但这是一个简单的例子:
(function() {
var x = 0;
for (var i = 0; i < 100; i++)
x += i;
alert (x);
}());
// here x and i are not accessible because they're local to the function above.