We can use the form: varable.property
to get and set the value of an object: var obj = {a:1}
in JavaScript. This is the most common and convenient way we code in JS, however the property that is created in this way can be easily modified and is enumerable. The Object.defineProperty() allows precise addition to or modification of a property on an object. It has been widely used in some popular two-way binding JS libraries.
Syntax
The Object.defineProperty() accepts three arguments:
Object.defineProperty(obj, prop, descriptor)
Arguments
Parameter name | Type | Description |
---|---|---|
obj | Object | The object on which to define the property |
prop | String | The name of the property to be defined or modified |
descriptor | Object | The descriptor of the property to be defined or modified |
Return Value
The object that was passed to the function.
Descriptor
The third parameter accepts an object to describe the details of the property to be defined or modified. Following attributes are allowed.
Attribute | Description | Default value |
---|---|---|
configurable | Whether the property can be deleted and its descriptor can be changed | false |
enumerable | Whether the property can be enumerated using `for...in` and be listed using Object.keys(obj) | false |
value | The value associated with the property | undefined |
writable | Whether the value associated with the property can be changed with an assignment operator ("=") | false |
get | A function which serves as a getter for the property | undefined |
set | A function which serves as a setter for the property | undefined |
Configurable & Enumerable
- Once the configurable attribute is set to false, the Object.defineProperty() method can no longer change the attributes of the property and the property cannot be deleted.
- If the enumerable attribute is set to true, then the property can be enumerated using
for...in
and shows up in the result of Object.keys().
var obj = {};
Object.defineProperty(obj, 'name', {
value: 'John',
configurable: true,
enumerable: true
});
Object.keys(obj); // Array [ "name" ]
Object.defineProperty(obj, 'name', {
enumerable: false,
configurable: false
});
Object.keys(obj); // Array [ ]
Object.defineProperty(obj, 'name', {
enumerable: true
}); // TypeError: can't redefine non-configurable property "name"
delete obj.name; // false
obj.name; // "John"
Value & Writable
When the writable attribute is set to false, the value associated with the property cannot be be changed with an assignment operator, but we can still use Object.defineProperty()
method to reassign the value.
var obj = {};
Object.defineProperty(obj, 'name', {
value: 'John',
writable: false,
configurable: true
});
console.log(obj.name); // "John"
obj.name = 'Marry';
console.log(obj.name); // "John"
Object.defineProperty(obj, 'name', {
value: 'Marry'
});
console.log(obj.name); // "Marry"
var obj = {};
obj.name = 'John';
Is equivalent to:
var obj = {};
Object.defineProperty(obj, 'name', {
value: 'John',
writable: true,
configurable: true,
enumerable: true
});
Getter && Setter
- get function is called when getting the property value, the function returns the property value
- set function is called when setting the property value using an assignment operator ("=")
- setter and getter functions cannot coexist with the value attribute
var Person = function(name) {
var nameValue;
Object.defineProperty(this, 'name', {
set: function(name) {
nameValue = name.substr(0, 1).toUpperCase().concat(name.substring(1));
},
get: function() {
return nameValue;
}
});
this.name = name;
};
var john = new Person('john');
console.log(john.name); // "John"
Browser compatibility
- Chrome 5 +
- FireFox 4 +
- IE 9+
- Opera 11.60 +
- Safari 5.1 +