Getters and Setters in JavaScript
Getters and setters are very important in back-end languages, but they never seemed to have gained much popularity in JavaScript. In fact, it’s not an easy task to find documentation about a good way to handle them.
In JavaScript, a value is mostly a value that you can access for read or write freely. But with the rise of large AJAX applications and more and more logic going to the client side, it’s becoming ever more common to have properties that we want to protect from direct access, or even validate before assigning to our objects.
For this purpose, we have the getValue
/ setValue
pattern, which works just like a Java developer would expect:
function Field(val){
var value = val;
this.getValue = function(){
return value;
};
this.setValue = function(val){
value = val;
};
}
But this is quite verbose and ugly. This is where ECMAScript 5 comes in:
var person = {
get fullName() {
return this.firstName + ' ' + this.lastName;
},
set fullName (name) {
var words = name.toString().split(' ');
this.firstName = words[0] || '';
this.lastName = words[1] || '';
}
}
person.fullName = 'Bryan Singer';
alert(person.firstName); // alerts Bryan
alert(person.lastName) // alerts Singer
Using this syntax, you can later assign or get a value, just like any other property, using different functions for each operation.
If you need to, you can also define your setters and getters after the object definition using Object.defineProperty
.
var Child = {};
Object.defineProperty(Child, 'old', {
get: function() { return this.age },
set: function(value) { this.age = value - 2 }
})
Child.old = 7;
console.log(Child.old); // 5
Just make sure to never mix the get/set with any other property name. What I mean by this is, in the last example, you can’t have another this.old
property. For example, if our setter looks like so:
set: function(value) { this.old = value }
we’d end up having a Maximum call stack error, because the setter would be infinitely calling itself…
Setters and getters can be used to extend prototypes, and also to validate some data. Have in mind that Object.defineProperties
allows you to set more than one property at a time:
var Person = function() {};
Object.defineProperties(Person.prototype, {
'fullName': {
get: function() {
return this.firstname + ' ' + this.lastName
},
set: function(value) {
var parts = value.split(' ');
if (parts.length == 2) {
this.firstName = parts[0];
this.lastName = parts[1];
}
}
}
});
var p = new Person();
p.fullName = "Maxi Benedetto";
alert(p.firstName); // Maxi
alert(p.lastName); // Benedetto
This get/set syntax is supported in all major browsers, except for IE < 9, and in Node.js as well.
There is an older syntax, __defineGetter__
and __defineSetter__
, but it’s deprecated so you shouldn’t pay attention to it anymore.
Let me know what you think by leaving a comment below!
Cheers!
Everybody’s talking about JavaScript’s too loose with types and I’m just over here like “Use your getter/setters, friend.”