最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Should one use getters and setters for private variables? - Stack Overflow

programmeradmin2浏览0评论

I'm using JavaScript objects like this:

var obj = new Foob;

should I pretend like there is a private way and do:

obj.get('foo');

or should I just try to access directly as :

obj.foo

I'm using JavaScript objects like this:

var obj = new Foob;

should I pretend like there is a private way and do:

obj.get('foo');

or should I just try to access directly as :

obj.foo
Share Improve this question edited Aug 25, 2016 at 3:47 FurkanO 7,3085 gold badges27 silver badges39 bronze badges asked Apr 21, 2013 at 21:01 user1637281user1637281 6
  • Depends on purpose and if the situation requires. But nothing is "private" in JS anyway. – Joseph Commented Apr 21, 2013 at 21:03
  • 1 that's why I said pretend – user1637281 Commented Apr 21, 2013 at 21:03
  • How about js getters and setters? stackoverflow.com/questions/15735821/… – louisbros Commented Apr 21, 2013 at 21:05
  • ...I know about getters/setters – user1637281 Commented Apr 21, 2013 at 21:07
  • Well, you didn't mention them in your question. Instead, you asked if you should use get('foo'), which would be a rather odd way to expose that property. – JLRishe Commented Apr 21, 2013 at 21:26
 |  Show 1 more comment

3 Answers 3

Reset to default 12

You can actually have variables which can only be accessed through setters and getters in Javascript:

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

Or if you want a generic 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;
    }

}

One least known feature of Javascript is that it supports getters and setters natively.
When defining a property, you can either define it simply by :

someObj.prop = 12;

OR you can define getters and setters , using Object.defineProperty and the reserved words get and set :

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

A way of using such getters/setters inside a 'class' to get a private variable would be :

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. 

so you have a truly private variable, armed with a getter and a setter.

Obviously, there is not much interest to use getters/setters code , unless you want to make bound-checking/type-checking or have a another specific reason.

I used to like the idea of getters and setters when I started using object-oriented JavaScript heavily, but that is because I was coming from a Java background.

ES5 supports getters and setters through a special syntax

See John Resig's explanation:

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

My take is to think about why getters/setters are useful. It's so one has a way to encapsulate a variable's access so that it can be intercepted / controlled. If calling code directly mutates another object's instances variables, then you can't change it transparently. Needing to catch all of these mutations requires changing variable scope, adding a getter and setter and altering all calling code.

However, this syntax is transparent to calling code. Therefore, you can simply allow a property to be directly controlled and then if you need to intercept it, to say add a console.log for debugging, you can ADD a getter and setter and it will just work.

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

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

The downside to the getter/setter syntax is that it doesn't actually make your variable private, it only "hides" it so that you can use some secret internal name, unless you define it within the constructor as Vincent indicated.

To get truly private:

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);
发布评论

评论列表(0)

  1. 暂无评论