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
|
Show 1 more comment
3 Answers
Reset to default 12You 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);
pretend
– user1637281 Commented Apr 21, 2013 at 21:03get('foo')
, which would be a rather odd way to expose that property. – JLRishe Commented Apr 21, 2013 at 21:26