我可以使用立即调用来创建一个对象,该对象的方法可以访问私有(private)成员。
var myObj = (function () {
// Private member variables
var privateX;
function setPropX (value) {
privateX = value;
}
function getPropX () {
return privateX;
}
function init() {
privateX = "Initial value privateX";
}
init();
// Public API
return {
// Methods
"setPropX": setPropX,
"getPropX": getPropX
};
}());
此后,我可以使用公共(public) API 很好地处理该对象,但我的私有(private)成员已正确隐藏:
myObj.setPropX("Hello world");
alert(myObj.getPropX()); // --> Hello world
alert(myObj.privateX); // --> Undefined
现在回答我的问题:
是否可以向对象添加公共(public)属性,以便调用者和我的代码中都可以访问该对象?然后它们将像这样使用:
myObj.publicY = "ABC";
myObj.sayPublicY(); // Should alert --> ABC
我尝试这样做:
var myObj = (function () {
// Private member variables
var self = this;
var privateX;
function setPropX (value) {
privateX = value;
}
function getPropX () {
return privateX;
}
function sayPublicY () {
alert(self.publicY);
}
function init() {
privateX = "Initial value privateX";
self.publicY = "Initial value publicY";
}
init();
// Public API
return {
// Methods
"setPropX": setPropX,
"getPropX": getPropX,
"sayPublicY": sayPublicY
};
}());
我以为这会起作用,但事实并非如此。闭包中保存的 self 引用正在引用 window 对象。为什么它不引用 myObj
?
我一定错过了一些明显的东西,但我在 Google 或 SO 上找不到任何东西。
正确的做法是什么?
编辑:添加了仍不起作用的 init() 方法的详细信息
最佳答案
因为在你的闭包中 this
(var self = this;
) 等于 window
而不是你创建的实例。这个 self
声明是没有用的;因为它总是等于窗口
,并且应该被删除(并且不使用)。
this
的解析会延迟到执行时,但是由于您专门使用 self
而不是 this
,因此您始终使用窗口
。将 sayPublicY
中的 self
更改为 this
,这样就可以工作了。
使用这种构造形式的 init
函数是无效的。此代码中的构造函数
是以下几行:
return {
// Methods
"setPropX": setPropX,
"getPropX": getPropX,
"sayPublicY": sayPublicY
};
直到这几行,您还没有 myObj
的实例。您只需拥有可以添加到 myObj
对象中的私有(private)变量/方法的定义和声明。 return 语句构造您的 myObj
,并为其分配方法 setPropX
、getPropX
和 sayPublicY
。您还应该在此处添加 publicY
属性:
return {
// Methods
"setPropX": setPropX,
"getPropX": getPropX,
"sayPublicY": sayPublicY,
"publicY": "Initial Value of Public Y"
};
关于Javascript:如何在立即调用创建对象时访问公共(public)成员变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7847376/