Reputation: 2709
When defining an object literal its possible to use a self-invoking function so the function has access to private variables,
obj={
value:(function(){
var private;
return function(v){
return (private = v ?? private)
}
})()
};
But is it possible to do the same thing with a getter/setter in an object literal?
obj={
get value(){
return value;
},
set value(v) {
value=v;
}
};
Upvotes: 7
Views: 5856
Reputation: 122878
[edit 2022] A pretty old answer.
The IIFE from the initial answer is actually a factory function. It creates an object with (get and set) access (through the closure) to a private variable. It's reusable.
const obj1 = objFactory(`Hello`);
const obj2 = objFactory(`World`);
console.log(`${obj1.privateThing} ${obj2.privateThing}`);
obj1.privateThing = `Goodbye`;
console.log(`${obj1.privateThing} ${obj2.privateThing}`);
function objFactory(somethingPrivate) {
return {
get privateThing() { return somethingPrivate; },
set privateThing(value) { somethingPrivate = value; }
};
}
The old answer:
Not really. You can also create an Immediately Invoked Function Expression (IIFE) for obj
though:
obj = function(){
var privatething = 'hithere';
return {
get value() {
return privatething;
},
set value(v) {
privatething = v;
}
};
}();
obj.value; //=> 'hithere';
obj.value = 'good morning to you too';
obj.value; //=> 'good morning to you too'
Upvotes: 12
Reputation: 548
As per ES6 and later style, default values can also be set in the signature.
const _ = function(_x = 'leafy greens', _y = 'chicken', _z = 'noodle soup') {
// console.log(_x)
return {
_x,
_y,
_z,
get x() { return this._x },
set x(value) { this._x = value }
}
}()
console.log(_.x)
_.x = 'beef & pork'
console.log(_.x)
Upvotes: 6
Reputation: 8731
This works.
var obj = {a:1};
console.log(obj.a); //1
Object.defineProperty(obj,"a",{
get: function(){
return this.b;
},
set: function(x){
this.b = x;
},
configurable:true,
});
obj.a = 10;
console.log(obj); //10
for(var key in obj)
{
console.log(key)
}
If you don't want the property b
to be enumerated while using for...in
loop or Object.keys()
, just add the line
Object.defineProperty(obj,"b",{enumerable:false})
Note : The above code can also be used as a listener, to detect changes in the property's value. (By implementing the needed function in the set
method, after setting the value.)
var obj = {a:1};
console.log(obj.a); //1
Object.defineProperty(obj,"a",{
get: function(){
return this.b;
},
set: function(x){
this.b = x;
console.log("obj.a value has been changed to "+x);
},
configurable:true,
});
obj.a = 10;
obj.c = 20;
obj.a = 30;
Upvotes: 0