自调用函数返回闭包.这是干什么用的?
JavaScript: self-calling function returns a closure. What is it for?
研究一个JavaScript库,我发现以下结构:
theMethod: function () {
var m1 = new SomeClass();
return function (theParameter) {
this.someMethod();
m1.methodCall(this.someField1);
this.someField2 = 'some value';
}
}()
方法被调用如下:
c.theMethod(paramValue);
作者想用这个声明表达什么?
为什么不使用这样的声明:
theMethod: function (theParameter) {
var m1 = new SomeClass();
this.someMethod();
m1.methodCall(this.someField1);
this.someField2 = 'some value';
}
在函数外部声明变量使得函数每次都使用相同的对象。
示例(为简单起见,使用整数代替对象):
var c = {
theMethod: function () {
var m1 = 0;
return function (theParameter) {
m1++;
console.log( m1 );
}
}()
};
c.theMethod(); c.theMethod(); // output: 1 2
var d = {
theMethod: function () {
return function (theParameter) {
var m1 = 0;
m1++;
console.log( m1 );
}
}()
};
d.theMethod(); d.theMethod(); // output: 1 1
自调用函数是这样工作的:
var c = {
theMethod: function () {
var m1 = 0;
return function (theParameter) {
m1++;
console.log( m1 );
}
}()
};
当对象c
被创建时,自调用函数调用自己,并且theMethod
现在等于该函数的返回值。在这种情况下,返回值是另一个函数。
c.theMethod = function( theParameter ) {
m1++;
console.log( m1 );
};
变量m1
对于函数是可用的,因为它在函数定义时处于作用域中。
从现在开始,当你调用c.theMethod()
时,你总是在执行从自调用函数返回的内部函数,该函数在对象声明时只执行一次。
自调用函数就像任何函数一样工作。考虑:
var c = {
theMethod: parseInt( someVariable, 10 )
};
不要期望每次使用c.theMethod
变量时都执行parseInt()
。将parseInt
替换为原始的匿名函数,结果完全相同。
用于封装。m1对其他方法和可能使用theMethod的地方的外部访问是隐藏的。Javascript程序员通常不关心封装(但对于重要的脚本,他们应该关心),因为需要使用闭包,这会使类的设计变得复杂,而且如果实现得不好,可能会降低性能。这就是为什么在库之外你很少看到这种结构。
第二段代码也不相等。等价的是:
theMethod: function (theParameter) {
if (typeof this.prototype.__private__ === "undefined") {
this.prototype.__private__= {}
}
if (typeof this.__private__.m1 === "undefined") {
this.prototype.__private__.m1= new SomeClass();
}
this.someMethod();
this.__private__.m1.methodCall(this.someField1);
this.someField2 = 'some value';
}
但是这里m1并不是私有的
还要注意,在这段代码中,m1只对返回的函数可见,如果theMethod是类的成员,则该类的其他方法将无法看到m1(这与Java中的"private"关键字不同)。也取决于你如何声明的方法m1将是java等效的"静态"(m1是一个函数在一个对象的原型,它是静态的,如果它不是在一个原型,它不是静态的)。
@Juhana是对的。这里有一个关于闭包如何工作的方便教程。http://www.javascriptkit.com/javatutors/closures.shtml
作者想用这个声明表达什么?
每次调用都应该重用m1
值。在无闭包的替代方案中,它将在每次调用时实例化一个新的SomeClass
对象。它可以简单地用于性能改进,或者(和)维护m1
对象中的公共状态。
- 如何使jQuery插件函数可调用以供独立使用,而不在集合上操作
- D3在一个调用中绘制不同的SVG形状,没有可见性
- 如何从Java/scala调用js美化程序
- 如何调用这个匿名 JavaScript 函数
- 如何从模块链中调用函数.导出到节点中
- 我需要从php调用javascript或jquery
- Chrome开发工具(如何知道我在调用哪个javascript对象)
- 单击按钮后如何逐个调用分区,上一个分区将隐藏
- 另一个ajax调用中的Jquery ajax调用在for循环中没有按预期工作
- Twitter Bootstrap typeahead:使用“this”获取上下文/调用元素
- node.js:setInterval()正在跳过调用
- 如何在单击复选框后调用控制器方法
- 如何在JQuery函数中定义一个值,然后调用另一个函数并使用该值
- 使用Google Visualization动态调用构造函数
- 如何在webView,Android中从@JavascriptInterface方法调用Javascript
- 是否可以将一个函数输入连接到另一个函数调用的文本
- 调用函数内部的函数
- 函数未在Object.keys或Object.getOwnPropertyNames下列出,但可以调用
- Javascript/jQuery中的并行Ajax调用
- 自调用函数返回闭包.这是干什么用的?