2

大家好,我现在是这样的:

var Human=function(){
  this._a=Math.random();
};
(function() {
  var before_get = function(human) {
  };
  var before_set = function(human, v) {
  };
  Human.prototype={
    get A(){
      before_get(this);
      return this._a;
    },
    set A(v){
      before_set(this, v);
      this._a=v;
    }
  };
})();
alert(new Human().A); // test
alert(new Human().A); // test

一切都很好,除了我不希望将变量_a暴露给原型以外的任何其他地方。好的,我进行了一些搜索并意识到这是不可能的,所以我想知道我们是否通常将其保留为这样(我的意思是我们只是让那些 _a 变量到处乱飞还是有更好的解决方案)?

4

2 回答 2

3

JavaScript 中没有私有这样的东西,所以这是无法实现的。一般来说,我们没有像其他 C#/Java 那样的通用属性或 setter/getter。

可以使用的模式是闭包而不是原型。

var Human = function() {
    var a = Math.random();
    var o = {};
    Object.defineProperties(o, {
        "A": {
             "get": function() {
                 return a;
             }, 
             "set": function(val) {
                 a = val;
             }
        }
    });
    return o;
}

一般来说,尽管您不应该将属性写入原型。原型应该包含方法。

唯一的清理方法this._a如下

var Human = (function() {
  var Human=function(){
    this._a=Math.random();
  };
  var before_get = function(human) {
  };
  var before_set = function(human, v) {
  };
  Human.prototype={
    getA(){
      before_get(this);
      return this._a;
    },
    setA(v){
      before_set(this, v);
      this._a=v;
    }
  };
  return function(args) {
     var h = new Human(args);
     return {
       getA: h.getA.bind(h),
       setA: h.setA.bind(h)
     }
  }
})();
于 2011-04-20T17:58:03.597 回答
1

这是使用原型“继承”创建私有/静态变量之类的方法。诀窍是在构造函数中定义原型方法(一次)。价格是您必须执行的 getter/setter。好处是简单和真正的原型解决方案(这毕竟是野兽的真实本性)。顺便说一句,在这里您只创建一次“getter/setter”,并且它适用于您从中创建的所有 999(999) 个实例。

function Human() {
    var  a = 'We are all Human',
         o = {}
         proto = Human.prototype;
    if (!proto.A) {
       //uncomment and create a few instances to see
       //this is only executed once
       //console.log('adding prototypes');
       proto.A = function() {return a;};
       proto.set = function(val) {a = val || a;};
       proto.setName = function(val) {this.name = val || ''};
       proto.getName = function(){
           if (!this.name) {this.setName('no name yet');}
           return this.name;};
    }
}

var Pete = new Human,
    Jean = new Human;

console.log(Pete.A()+':'+Jean.A()); 
      //|=> We are all Human:We are all Human
Pete.set(Pete.A()+' except Jean'));
console.log(Pete.A()+':'+Jean.A()); 
      //|=> We are all Human except Jean:We are all Human except Jean
Pete.setName('Hi, I am Pete. '+Pete.A());
Jean.setName('Hi, I am Jean. ' +Jean.A()+ '. Damn! thats me!');
console.log(Pete.name); 
      //|=> Hi, I am Pete. We are all Human except Jean
console.log(Jean.name); 
      //|=> Hi, I am Jean. We are all Human except Jean. Damn! thats me!

您必须意识到任何人都可以决定将其他内容分配给Human.prototype.A. 但是,如果他们在构造函数之外执行此操作,则闭包和因此a不再可用。

于 2011-04-20T19:27:31.547 回答