var Counter = (function() {
这是名为 的对象的创建Counter
。它是通过匿名自调用函数创建的。但由于该函数是自调用的,因此不建议将其命名为大写。
var privateCounter = 0;
privateCounter
正在设置“私有”变量。从某种意义上说,它是私有的,您无法直接从外部访问它。它是在一个匿名函数的范围内创建的,这使得它与它的包含函数 - 分开Counter
。这就是您无法从外部访问它的原因,例如Counter.privateCounter === undefined
. 注意:每当您尝试this
从匿名函数访问时,结果将是window
对象,但您无法使用window.privateCounter
.
function changeBy(val) {
privateCounter += val;
}
这是一种“私人”方法,Counter.changeBy() === undefined
. 这和做的一样var changeBy = function(val){}
。如果您想让属性或方法“公开”(可从外部访问),您必须像这样定义它们:
this.publicCounter = 0;
this.changeBy = function(val)...
这是通常的方法,当您的对象不是通过匿名函数创建时(检查上面的评论this
),但在这种情况下,您可以像这样创建它们:
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
};
这些仍然是 的“公共”方法Counter
,它们是Counter
对象范围的一部分。您可以像在警报中一样访问它们。
})();
这意味着该函数是自调用的,例如它正在立即执行。
现在,在我继续之前...当您启动脚本时,对象Counter
被创建,因为它是一个自调用函数。这将创建该对象的范围和它的匿名函数的另一个范围(具有一个“私有”属性和一个“私有”方法)。三个返回的方法在 的范围内Counter
,但它们可以访问它的匿名函数的范围,即使该函数已经返回。那是因为这三个方法都指向那个范围,它们仍然有“一些业务”,所以垃圾收集器不会触及内部变量。返回匿名函数后,您可以访问其中的值的唯一方法是通过它返回的方法(如果有的话)。希望这很清楚。现在,让我们继续。
alert(Counter.value()); /* Alerts 0 */
这调用对象value()
的方法Counter
。该方法进入已经返回的匿名函数的范围,并返回一个局部变量的值。
Counter.increment();
Counter.increment();
再次调用对象的“公共”方法,该方法可以访问已返回函数中的本地函数。
alert(Counter.value()); /* Alerts 2 */
和以前一样。但请注意,这privateCounter
是在已经返回的函数的范围内。您不是在创建一个新的,只是通过一些具有独占权的方法访问旧的仍然可以看到它。
Counter.decrement();
alert(Counter.value()); /* Alerts 1 */
和以前一样。
基本上,这就像调用一个勤杂工(对象),而勤杂工总是带着他的技能(“公共”方法和属性)和工具(“私有”方法和属性)。如果您需要做某事,请打电话给杂工并告诉他该做什么,该使用哪种技能,但没有他您无法使用他的工具。而且他有他的工具集,每次你打电话给他时他都不会买新的。他的钳子和你上次他进去时踩断的旧钳子一样。