Javascript is a powerful interpreted language that gives the developers a lot of flexibility. As the language has matured, it is fast enough that it can also be a compilation target. The tradeoff of speed is functionality - and object properties are a prime example.
Note: Once Javascript is interpreted, its in-memory performance is faster than most other languages and offers asynchronous handling.
The following code shows the fast way of making an object with a property, and the robust way of making an object with properties.
var fastObject = function () {
var self = this;
self.prop = 1;
}
var powerfulObject = function () {
var self = this;
Object.defineProperties(self, {
"prop" : {
"get": function() {
// _prop is not really private, but just pretend
return self._prop;
},
"set": function(value) {
self._prop = value;
}
}
});
};
// And if you really like closure notation
var powerfulClosureObject = (function () {
function obj() {
var self = this;
Object.defineProperties(self, {
"prop" : {
"get": function() {
return self._prop;
},
"set": function(value) {
self._prop = value;
}
}
});
}
return obj;
}());
Now the following code can be written:
var q = new fastObject();
q.prop = 2;
var p = new powerfulObject();
p.prop = 2;
Note: The keyword 'var' must be used - otherwise the object will be evaluated immediately.
So far, it just seems like the second object is just extra work. However, it's pretty useful if you want to apply constraints on properties.
var powerfulObject = function () {
var self = this;
Object.defineProperties(self, {
"prop" : {
"get": function() {
if (typeof(self._prop) != "number") {
throw "object not initialized";
}
return self._prop;
},
"set": function(value) {
if (typeof(value) != "number") {
throw "prop must be a number";
}
self._prop = value;
}
}
});
}
Using this approach...
var p = new powerfulObject();
console.log(p.prop); // fail "object not initialized"
p.prop = "test"; // fail "prop must be a number"
p.prop = 2; // success
console.log(p.prop); // displays 2