JavaScript doesn’t inherently support properties in the same way that .net languages do, which is a shame since the syntax really helps simplify access internalized data in a structured way.
There’s a common solution to this in JavaScript, that exploits the fact that JavaScript function arguments are optional. A property function will have a single argument. If the argument is undefined then the current call is a ‘get’, otherwise it’s a ‘set’. jQuery has many good examples of this, for example the val() method:
var value = $('input').val(); // Getter
$('input').val(123); // Setter
It isn’t particularly hard to define a method this way, below is an example class with a single property, ‘name’:
// A new class
var MyClass = function() {
var _name;
this.name = function(value) {
if (value !== undefined)
_name = value;
return _name;
};
};
// Example usage
var instance = new MyClass();
instance.name('Phil');
var name = instance.name(); // name = 'Phil'
This way of doing things is achieves the desired effect, but ends up being overly verbose if you have a lot of properties that are just wrappers around a value, like an auto-implemented property is in C#.
I came up with the solution below while I was working on findthatrobot.com. It helps in the creation of auto-implemented like properties, as well as allowing the getter and setter to be customized, or just one of the two, creating a read-only or write-only property.
With this function a property can be created as such:
var MyClass = function() {
var customPropertyValue;
// Auto-implemented proeprty
this.prop1 = createProperty();
// Custom getter and setter
this.prop2 = createProperty({
get: function() { return customPropertyValue; },
set: function(value) { customPropertyValue = value; }
});
};
And here is the ‘createProperty’ function:
var createProperty = function(getSet) { var _value; var autoImplement = { get: function() { return _value; }, set: function(value) { _value = value; return _value; } };
getSet = getSet || autoImplement;
var get = getSet.get || function() { throw new Error('No get method defined for this property.'); }, set = getSet.set || function() { throw new Error('No set method defined for this property.'); };
return function(value) { if (value !== undefined) return set(value);
return get(); }; };Phil