我正在尝试了解(揭示)模块模式中 public`属性的工作方式。 Carl Danley "The Revealing Module Pattern"指出的一个优点是:
明确定义公共方法和变量,从而提高可读性
我们来看看这段代码(fiddle):
var a = function() {
var _private = null;
var _public = null;
function init() {
_private = 'private';
_public = 'public';
}
function getPrivate() {
return _private;
}
return {
_public : _public,
init : init,
getPrivate : getPrivate,
}
}();
a.init();
console.log( a._public ); // null
console.log( a.getPrivate() ); // "private"
调用null
时返回a._public
。我现在可以操纵那个公共财产,比如a._public = 'public';
。但我不能在我的对象内改变它。或者至少这些变化不会通过。我有点期待它"public"
,因为它之前由init
- 方法更新。
这是否真的意味着,我没有任何方法可以处理 public 属性?然后,这种模式中的 public 属性没有多大意义,对吧?我也试过没有运气(fiddle):
return {
_pubic : _public,
init2 : function() {
_public = 'public';
}
}
最后,但并非最不重要的是,我对整个return
声明有疑问。为什么不能仅使用return this;
将所有内容公开?由于this
应该是自调用函数的上下文,它不应该仅仅返回其中的传递吗?为什么我必须创建另一个返回的对象?在此fiddle中,它返回window
对象。
答案 0 :(得分:4)
这是否真的意味着我无法处理公共属性的任何方法?
不,这意味着您无法拥有公共变量。 var _public
是一个变量,无法从外部访问,当您修改私有变量时,这不会反映在您的公共._public
属性中。
如果您想公开,请使用属性:
var a = function() {
var _private = null;
function init() {
_private = 'private';
this._public = 'public';
}
function getPrivate() {
return _private;
}
return {
_public : null,
init : init,
getPrivate : getPrivate,
}
}();
我可以操纵公共财产,例如a._public =' public' ;.但是我无法在我的对象中改变它。
您可以在对象的方法中使用this
,如上所示。或者您使用a
来引用该对象,或者甚至可能存储对您返回的对象的本地引用。有关差异,请参阅here。
或者至少这些变化没有通过
是的,因为变量与属性不同(与Java等其他语言不同,全局变量除外)。在对象文字中导出public: _public
时,它仅获取_public
变量中的当前值,并使用它在对象上创建属性。没有对变量的持久引用,对其中的更改不会反映在另一个中。
为什么不能使用
return this;
将所有内容公开?因为这应该是自我调用函数的上下文,它不应该只是返回其中的传递吗?
变量是JavaScript中范围的一部分。 (除了全局范围之外)这些范围不是语言可访问的对象。
this
keyword不是指函数的这个范围,而是指调用提供的上下文。这可以是方法调用中的基本引用,构造函数调用中的新实例,或者像您的基本函数调用中的任何内容(或松散模式下的全局window
对象)。
答案 1 :(得分:2)
在您的模块定义中,with [1,2,3,4,5,6] as myarray
return myarray[0..3] + 999 + myarray[4..length(myarray)]
按值复制,因为在javascript中,仅通过引用分配对象。之后它没有任何链接到本地_public变量。因此,只有在对象中“封装”_public时才会起作用,因此它会通过引用复制,或者您也可以在模块中引用对象的属性,只有一个对局部变量的引用:
_public
答案 2 :(得分:0)
您可以使用此构造来创建新类
function a(){
var _private = null;
this.public = null;
this.getPrivate = function(){
return _private;
};
function init(){
_private = "private";
this.public = "public";
}
init.apply(this, arguments);
}
//static function
a.create = function(){
return new a();
};
//using
var b = new a();
//or
var b = a.create();