Defining properties in JavaScript
9th February 2014 | by Adam Beres-Deak | javascript
JavaScript has always supported basic properties on objects. But the time is approaching when IE8 support is not relevant anymore, so we can use a more modern approach (ES5) for defining properties. There is one difference though to other programming languages - like C# - that we always define properties on objects and not on types.
Defining properties on objects with Object.defineProperty()
var obj = {};
Object.defineProperty(obj, "myProperty", {
enumerable: false,
configurable: false,
writable: false,
value: 13
});
The first two arguments are very obvious, but the third one is where all the magic happens. This argument is a property descriptor. Let's see what we can do with it.
Enumerable
This attribute simply tells whether the property should show up in enumerations like for ... in
loops or in Object.keys()
.
Defaults to false
.
Configurable
This attribute sets whether the property can be reconfigured at a later point in the code or whether it can be deleted from the object.
Defaults to false
.
Writable
This attribute sets whether a property is read-only or not.
Defaults to false
except in Google Chrome.
Value
The value of a property can be anything, any valid JavaScript value (Number, Date, Array, Function, etc.).
Defaults to undefined
.
Defining getter and/or setter functions
It is also very easy to define getter and setter functions. Let's take a look at the example below:
var obj = {};
var propValue = 100;
Object.defineProperty(obj, "prop", {
get: function(){ return propValue; },
set: function(newValue){ propValue = newValue; },
enumerable : true,
configurable : true
});
Invalid cases
var obj = {};
Object.defineProperty(obj, 'undeletable', { value: 100, configurable: false });
console.log(obj.undeletable); // 100
delete obj.undeletable;
console.log(obj.undeletable); // 100
var obj = {};
Object.defineProperty(obj, 'notWorking', {
value: 100,
get: function() { return 300; }
});
// TypeError: Invalid property. A property cannot both have accessors and be writable or have a value, #<Object>
var obj = {};
Object.defineProperty(obj, 'notWorking', {
get: function() { return 300; },
writable: true
});
// TypeError: Invalid property. A property cannot both have accessors and be writable or have a value, #<Object>
Defining multiple properties on the same object
var obj = {};
Object.defineProperties(obj, {
"hello": {
value: "Hello",
writable: true
},
"world": {
value: "World!",
writable: false
}
});
Browser support
Good news, the Object.defineProperty()
is supported in all modern browsers. The only problematic one is Internet Explorer 8, which only allows to define properties on DOM objects).
Performance
At the moment, using Object.defineProperty()
is definitely slower than using basic properties like in the old days - but not that much. For more detailed performance tests take a look at jsperf.com.
Resources:
Latest blog posts
Displaying icons with custom elements 14th October 2015
Plain JavaScript event delegation 26th January 2015
After the first year of blogging - what happened on my blog in 2014? 1st January 2015
Better webfont loading with using localStorage and providing WOFF2 support 18th December 2014