I am messing around with some "classical" inheritance and I'm running into an issue. I am using Object.defineProperty()
to add properties to my LivingThing
"class". I want to have a default value, along with a property getter/setter.
/
I am running into the following error:
Uncaught TypeError: Invalid property. A property cannot both have accessors and be writable or have a value, #<Object>
Why am I getting this error and what would be the best approach to have a default value and a getter/setter for a property, using Object.defineProperty()
?
I am messing around with some "classical" inheritance and I'm running into an issue. I am using Object.defineProperty()
to add properties to my LivingThing
"class". I want to have a default value, along with a property getter/setter.
http://jsfiddle/fmpeyton/329ntgcL/
I am running into the following error:
Uncaught TypeError: Invalid property. A property cannot both have accessors and be writable or have a value, #<Object>
Why am I getting this error and what would be the best approach to have a default value and a getter/setter for a property, using Object.defineProperty()
?
- Depends. Are you using the setter to do anything special, or is the default value all the behavior you want? – Touffy Commented Sep 25, 2015 at 20:12
- The setter is just used to replace the old property value with a new value. I believe this is the default behavior, though I'm not sure. – Fillip Peyton Commented Sep 25, 2015 at 20:15
- OK so you don't actually need a setter and getter ;) – Touffy Commented Sep 25, 2015 at 20:16
3 Answers
Reset to default 5Use a function scoped variable to back the defined property and set that variable's initial value to the default:
function LivingThing(){
self = this;
var isAlive = true;
Object.defineProperty(self, 'isAlive', {
get: function(){
return isAlive;
},
set: function(newValue){
isAlive = newValue;
},
configurable: true
});
self.kill = function(){
self.isAlive = false;
};
}
http://jsfiddle/329ntgcL/5/
writable
isn't necessary because you have a setter. That's what's causing your error. You can either have value/writable (data descriptor) OR get/set (accessor descriptor).
As a result, when you call var l = new LivingThing
, l.isAlive == true
and after you call l.kill()
, l.isAlive == false
Your getter/setter pair presents a puted property, you can (and should) back that up with a real property if you need storage:
self._isAlive = true;
Object.defineProperty(self, 'isAlive', {
get: function(){
return this._isAlive;
},
set: function(newValue){
this._isAlive = newValue;
},
writable: true,
configurable: true
});
Presumably, put some logic there to justify a setter/getter vs a regular property. Setters are for wrapping property access.
Without a setter and getter, you can define a default value by just assigning it to the prototype:
LivingThing.prototype.isAlive = true
var o = new LivingThing()
console.log(o.isAlive) // true
Just to be clear, changing that property on an instance of LivingThing will create a property for that instance, not change the value in its __proto__
.
o.isAlive = false
console.log(new LivingThing().isAlive) // still true