2

我正在使用这样的 JavaScript 对象:

var obj = new Foob;

我应该假装有一种私人方式并做:

obj.get('foo');

还是我应该尝试直接访问:

obj.foo
4

3 回答 3

12

您实际上可以拥有只能通过 Javascript 中的 setter 和 getter 访问的变量:

function Foob(){

    var foo = 5;

    this.getFoo = function(){
        return foo;
    }


    this.setFoo = function(newFoo){
        foo = newFoo;
        return this;
    }

}

var obj = new Foob;
obj.getFoo(); // 5
obj.foo; // undefined

或者,如果你想要一个通用的 getter/setter:

function Foob(){

    // You can set default values in the data object
    var data = {};

    this.get = function(key){
        return data[key];
    }

    this.set = function(key, value){
        data[key] = value;
        return this;
    }

}
于 2013-04-21T21:06:39.063 回答
7

Javascript 的一个鲜为人知的特性是它原生支持 getter 和 setter。
定义属性时,您可以通过以下方式简单地定义它:

someObj.prop = 12;

或者您可以定义 getter 和 setter ,使用Object.defineProperty和 保留字getand set

Object.defineProperty ( someObj,    "prop" ,  
                                              { get : function () { return ??; } ,
                                                set : function (val) { /* store val */ }            } ;

在“类”中使用此类 getter/setter 来获取私有变量的方法是:

var MyClass = function() {
  var _private = 5;
  
  Object.defineProperty(this, "public", {
    get : function() { return _private; },
    set : function(val)  { _private=val; }
  });
  
  return this;
};

var anInstance = new MyClass();

anInstance.public = 12 ; 
console.log(anInstance.public)   ;  // writes 12
console.log(anInstance._private) ;  // writes undefined. 

所以你有一个真正的私有变量,配备了一个 getter 和一个 setter。

显然,使用 getter/setters 代码并没有太大的兴趣,除非您想进行边界检查/类型检查或有其他特定原因。

于 2013-04-21T21:10:09.467 回答
4

当我开始大量使用面向对象的 JavaScript 时,我曾经喜欢 getter 和 setter 的想法,但那是因为我来自 Java 背景。

ES5 通过特殊语法支持 getter 和 setter

请参阅 John Resig 的解释:

http://ejohn.org/blog/javascript-getters-and-setters/

我的看法是思考为什么 getter/setter 是有用的。它是如此有一种方法来封装变量的访问,以便它可以被拦截/控制。如果调用代码直接改变另一个对象的实例变量,那么你不能透明地改变它。需要捕获所有这些突变需要更改变量范围,添加 getter 和 setter 并更改所有调用代码。

但是,此语法对调用代码是透明的。因此,您可以简单地允许直接控制一个属性,然后如果您需要拦截它,例如添加一个 console.log 进行调试,您可以添加一个 getter 和 setter,它就可以工作了。

function Foob() {
}
Foob.prototype = {
  get foo() {
    return this._foo;
  },
  set foo(foo) {
    this._foo = foo;
  }
};

var o = new Foob();
console.log(o.foo);

getter/setter 语法的缺点是它实际上并没有使您的变量私有,它只是“隐藏”它以便您可以使用一些秘密的内部名称,除非您按照文森特的指示在构造函数中定义它。

要真正做到私密:

function Foob() {
  var foo;
  this.__defineGetter__('foo', function () { 
    return foo;
  });
  this.__defineSetter__('foo', function (_foo) {
    foo = _foo;
  });
}

var o = new Foob();
console.log(o.foo);
于 2013-04-21T21:26:14.847 回答