是否应该使用getter和setter作为私有变量?

时间:2013-04-21 21:01:07

标签: javascript setter getter

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

var obj = new Foob;

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

obj.get('foo');

或者我应该尝试直接访问:

obj.foo

3 个答案:

答案 0 :(得分:12)

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

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;
    }

}

答案 1 :(得分:7)

Javascript的一个最不为人所知的特性是它本身支持getter和setter 定义属性时,您可以通过以下方式定义它:

someObj.prop = 12;

或者您可以使用Object.defineProperty和保留字getset来定义getter和setter:

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代码没什么兴趣,除非你想进行边界检查/类型检查或者有其他特定原因。

答案 2 :(得分: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语法的缺点是它实际上并不使你的变量变为私有,它只是“隐藏”它以便你可以使用一些秘密的内部名称,除非你在构造函数中定义它,如Vincent所示。

要获得真正的私密性:

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);