Reputation: 4259
I am trying to create an object. But I dont understand why my property getters setters cannot simply call this.bar
. As such my foo object seems to end up with two properties.
Is this correct or am I:
creating foo
with a bar
property
var foo = function ()
{
Object.defineProperties(this, {
bar : {
get : function () {return this.barVal},
set : function(value) { this.barVal = value},
enumerable: true,
configurable: true
}
})
};
var o = new foo();
o.bar = "Hello";
console.log(JSON.stringify(o));
//output {"bar":"Hello","barVal":"Hello"}
Upvotes: 2
Views: 2143
Reputation: 1084
You are creating two properties, one named "bar" and the other named "barVal". "bar" is created by the defineProperties call and "barVal" is created by the this.barVal assignment in the set function. They both have a true value for their enumerable attribute (you explicitly set it for varVal, the assignment implicitly set it for barVal) so they are both listed by JSON.stringify.
If you intent is for barVal to be treated as a private value that does not show up in a JSON or for-in enumeration you can explicitly set its enumerable attribute to false:
var foo = function ()
{
Object.defineProperties(this, {
bar : {
get : function () {return this.barVal},
set : function(value) { this.barVal = value},
enumerable: true,
configurable: true
},
barVal : {
value: undefined,
enumerable: false, writable: true, configurable: true
}
})
};
Upvotes: 2
Reputation:
JSON.stringify activates the getter to resolve the property. Your setter sets a second property, so you end up seeing both. What you need is a way to store the "internal" value for foo.bar that isn't ON foo itself.
function Foo(){
var secret = {};
Object.defineProperties(this, {
bar: {
get: function( ){ return secret.bar },
set: function(v){ secret.bar = v },
enumerable: true,
configurable: true
}
});
}
var foo = new Foo;
foo.bar = 'Hello';
console.log(JSON.stringify(foo));
Upvotes: 5