Getters and setters
Sunday, August 23, 2009 at 01:36PM Mascara has supported getter and setter functions and methods for some time, but in anticipation of the forthcoming ECMAScript 5 standard it has now added support for getters and setters in object literals.
In short, getters and setters are special functions which are invoked the same way a variable or property is read or assigned.
Here is an example of a getter:
//defining a getter function x
function get x() { return 7; }
// the function is invoked by accessing the variable value:
var a = x; // (a is assigned the result of calling get x, i.e. 7)
This is pretty useful for encapsulating member access. A setter is the corresponding function which emulates assigning a value to a property or variable:
function set x(x) { alert(x) }
x = “hello”; // set x is invoked and shows an alert box with “hello”
Getters and setters (together known as “accessors”) are useful for various forms of encapsulation. For example we can perform validation on input, we can change the internal representation without changing the interface, or we can trigger events when a property is changed.
Getters and setters often appear together, but we can emulate read-only properties by only providing a getter, or (less commonly) write-only properties by just exposing a setter.
The new addition is that ECMAScript 5 defines a syntax for gettes and setters in object literals. Example:
var ecoStorage = {
// to save memory space we only save half the value
_storage : 0.0,
get x() { return ecoStorage._storage * 2; },
set x(value) { ecoStorage._storage = value / 2 }
};
ecoStorage.x = 100;
var y = ecoStorage.x; // y is assigned 100
So the accessors appear in the place of a name:value pair in an object literal.
Above we get a single object instance with the getter/setter pair. If we want to instiate multiple object, we have to create a constructor the object literal as a prototype. Hence:
function EcoStorage() {}
EcoStorage.prototype = {
_storage : 0,
get x() { return this._storage * 2; },
set x(value) { this._storage = value / 2 }
};
var storage1 = new EcoStorage;
storage1.x = 100;
var y = storage1.x; // y is assigned the value 100
This approach is also supported in Mascara, however I can’t say I find the syntax particularity attractive. I appreciate the flexibility declaring prototypes explicitly, but the syntax is not elegant.
The idiomatic way to do the same in Mascara is to use classes:
class EcoStorage {
var _storage : double = 0;
function get x() { return _storage * 2; }
function set x(value) { _storage = value / 2; }}
var s = new EcoStorage;
s.x = 100;
Note the slightly different syntax (function get instead of just get) for getters/setter when they appear outside of object literals.
The ECMAScript 5 spec only allows getters and setters in object literals. However there is a low-level way to defining getters and setters through the new Object.defineProperty() method. This requires support in the JavaScript engine and is therefore not available in Mascara. It is not necessaray either, since Mascara supports the more straightforward syntax shown above.
Getters/setters in classes and as stand-alone functions has been supported in Mascara for a while. The ES5 compliant syntax for getters/setters in object literals is new in Mascara 1.2
Have fun!
Olav |
2 Comments | 
Reader Comments (2)
Does mascara support e4x?
Hi enefekt. Mascara does not support E4X. However if there is interest, I will consider adding support for it. I have been a bit doubtful about how big the demand for E4X is these days, where it seem JSON is used more and more in place of XML in AJAX-apps. However if there is demand and use cases for it, I will seriously look into it.
(For the un-initiated: E4X is extensions that allow XML literals in JavaScript and special syntax for selecting attributes and child elements from elements. See eg, http://en.wikipedia.org/wiki/ECMAScript_for_XML The objective is to make it more straightforward to work with XML.)