这SO-question一直困扰着我。这是一个似乎在SO中定期重新出现的问题。
现在我已经设法创建一个构造函数,试图管理私有'属性'只能使用私有存储从构造函数原型get / set方法设置。在它的基本形式中它看起来像这样:
基本构造函数:
function Human(){
/** set up a property storage **/
var storage = {
name: { val: name || '-', get:true, set:true }
,age: { val: (age || '0'), get:true, set:true }
};
function get(){
if (get.caller !== Human.prototype.get &&
get.caller !== Human.prototype.set ){ return null }
return storage;
}
this._get = get;
}
将get / set prototype方法添加到Human
Human.prototype = {
get: function(prop){
return this._get()[prop];
}
,set: function(prop, val){
var storage = this._get();
/**
set functionallity, returning
the current object after setting
see jsfiddle link @ the bottom of
this question
**/
return this;
}
};
// usage
var pete = new Human('Pete',23);
pete.get('name'); //=> 'Pete'
pete.set('name','Pete Justin');
pete.get('name'); => 'Pete Justin'
// but
pete.name; //=> 'undefined'
我对你的评论非常感兴趣。也许我正在思考一个完全错误的方向,也许你说这是一个不必要的操作,违反了js的原型性质,它已经在其他地方已经完成(并且更好),或者其他什么。请告诉我!
我对此的看法 - 好吧在这里让我们称之为 - 模式:你使用它的简单方法是简单地声明和获取属性(this.some = that
等),你是什么win是更好的封装,实例变量的隐私和对你使用的属性的一些控制(不确定它是否是正确的术语,但是在OOP世界中它有时看起来每个人都赋予它自己的术语私有意义)。
无论如何,我已经在this jsfiddle制作了一个更完整且更有效的Human
。
.caller
的私有替代方案,但仍然可以使用私有存储:请参阅this jsfiddle 答案 0 :(得分:2)
首先,这个过度设计的解决方案试图解决什么?
尝试从原型访问构造函数局部变量的问题不是问题。人们要么只需要使用原型并将所有数据存储在this
上以获得较小的速度增益,或者不要抱怨为每个对象创建额外的功能(最小的开销)。这是一个常见的误解,即为每个对象创建额外的功能是很昂贵的。
没有冒犯,但代码过于设计,复杂,似乎是一种阅读或维护的正确痛苦。我认为这种方法没有任何优势?为什么不让this._store
成为特权函数。
另外,在构造函数中有一个局部函数这一事实意味着你失去了使用为所有对象提供一个函数的原型的优势。我也过度设计了一个类似于此的解决方案来“模拟”私有变量,代码变得一团糟,我不得不放弃它。
至于代码批评:
.caller
是非标准的。你不能使用它。这是一个黑客攻击。
this._store = {get:get};
为什么不只是this._store = get
?
这个
function thisget(prop){
return storage[prop];
}
return thisget(prop);
应该内联到
return storage[prop]