【发布时间】:2011-05-15 19:41:29
【问题描述】:
这个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;
}
为Human添加get/set原型方法
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'
我对你们的 cmets 真的很感兴趣。也许我在想一个完全错误的方向,也许你说这是一个不必要的操作,违反了 js 的原型性质,它已经在其他地方做过(并且更好),或者任何事情。请告诉我!
我对此的看法 - 好吧,我们称之为 - 模式:您使用它松散的是简单地声明和获取属性(this.some = that 等),您赢得的是更好的封装、实例变量的隐私以及对您使用的属性的一些控制(不确定这是否是正确的术语,但在 OOP 世界中,有时看起来每个人都对术语赋予了自己的私人含义)。
不管怎样,我已经在this jsfiddle 中制作了一个更完整、更有效的Human。
- [edit1] 回应评论:放弃了立即调用函数 (iif)
- [edit2] 没有
.caller的私有替代方案较少,但仍然可以使用私有存储:请参阅this jsfiddle - [edit3]也可以ditch the prototype@
- [edit4] 完整:这是一个真正的prototypal get/set variant
【问题讨论】:
-
我很好奇构造函数中立即调用函数的原因。似乎您可以将
storage设为构造函数私有,然后直接公开get方法this._store = {get: get};。但也许我错过了一些东西。另外,我认为.caller属性的日子已经过去了。你会在"strict mode";中得到一个TypeError。 -
@patrick:afaik 的日子是为
arguments.caller编号的,而不是function.caller。是的,storage也可以是构造函数本身的私有变量,很好的调用。它在 iif 中(不,这不是 ms-access;)是所有摆弄的残余。没有特别的理由。 iif 可以被抛弃,正如这个 fork 所示:jsfiddle.net/KooiInc/H2fU5 -
我不想这么说,但在15.3.5 Properties of Function Instances 你会发现:"对应于严格模式函数(13.2)的函数实例和使用Function.prototype.bind 创建的函数实例方法 (15.3.4.5) 具有名为“caller”和“arguments”的属性,它们会引发 TypeError 异常。ECMAScript 实现不得将任何特定于实现的行为与从严格模式函数代码对这些属性的访问相关联。
-
@patrick:保持冷静,我从不向信使开枪。是的,你是对的。如果您在我创建的小提琴中添加严格模式,您可以在 FF4 中测试您的正确性(正义?我是荷兰人,抱歉)。现在我将省略严格模式。你会碰巧知道一个可行的替代方案吗?
-
@KooiInc:我认为你在寻找“正确性”,因为没有一个是正义的,不,没有一个。 :o)
标签: javascript prototype-programming private-members