Custom Getters and Setters with MooTools

By  on  

Working with Dojo all day and scoping out MooTools at night gives me a unique perspective; I get to constantly evaluate the two frameworks and mentally move functionalities from framework to framework. One small but handy feature within the Dojo Toolkit's Dijit UI Framework is its set/get system. Dijit allows developers to add custom methods tied into simple get and set methods to allow manipulation properties into and on the way out of a class. I took a few moments to implement this system in MooTools.

The idea is that a Class instance has properties:

var MyClass = new Class({
	value: 10/*, more... */
});

Instead of simply setting and getting object properties directly, sometimes they need to be treated before coming in or going out. For setting, it can be a sort of internal formatting or validation. For getting, it's mostly formatting. The method formats are _get[SomeAttrName]Attr and _set[SomeAttrName]Attr. With that in mind, it's time to create the mixin class.

JavaScript GetSet for MooTools

This new functionality will be independently coded as a class meant as a Class mixin using the Implements property:

(function() {
	
	// Turns "thisPropertyName" into "ThisPropertyName"
	function getFunctionName(key, getSet) {
		return "_" + getSet + key.charAt(0).toUpperCase() + key.slice(1) + "Attr";
	}
	
	// Implement the getter / setter
	this.GetSet = new Class({
		// A custom getter that looks for _get
		get: function(key) {
			var fn = this[getFunctionName(key, "get")];
			return (fn && fn.call(this, key)) || this[key];
		},
		set: function(key, value) {
			var fn = this[getFunctionName(key, "set")];
			if(fn) {
				fn.call(this, value);
			}
			else {
				this[key] = value;
			}
			// Returning "this" to allow chaining
			return this;
		}
	});
	
})();

The GetSet will feature two method, get and set, and will check for the presence of custom set and get methods; if so, those methods are called, and if not, the property is simply set or returned. Now let's look at a sample usage:

// Create a test class
var TestClass = new Class({
	// Implement the new class
	Implements: [GetSet],
	// The custom getter
	_getValueAttr: function() {
		return this.value / 10;
	},
	// The custom setter
	_setValueAttr: function(value) {
		this.value = value * 10;
	}
});

// Create a test class instance
var inst = new TestClass({
	value: 8
});

/*
	inst.set("value", 20);  // inst.value = 200
	inst.get("value");  // inst.value = 20
*/

In this case, we've set custom get and set methods which will handle the class' value property. On the way in, the value is multiple by 10 and then set on the object. On the way out, the value is divided by 10. Of course, not the most realistic of scenarios, but this example provides a very simple illustration of how these methods can be used.

So what would be a more realistic scenario? As I said above, custom setters can be very useful as an internal validator. Both the getters and setters are valuable, however, because they also provide a way to "spy" on object properties and have multiple reactions to their changes.

Recent Features

  • By
    9 More Mind-Blowing WebGL Demos

    With Firefox OS, asm.js, and the push for browser performance improvements, canvas and WebGL technologies are opening a world of possibilities.  I featured 9 Mind-Blowing Canvas Demos and then took it up a level with 9 Mind-Blowing WebGL Demos, but I want to outdo...

  • By
    JavaScript Promise API

    While synchronous code is easier to follow and debug, async is generally better for performance and flexibility. Why "hold up the show" when you can trigger numerous requests at once and then handle them when each is ready?  Promises are becoming a big part of the JavaScript world...

Incredible Demos

  • By
    Truly Responsive Images with responsive-images.js

    Responsive web design is something you hear a lot about these days. The moment I really started to get into responsive design was a few months ago when I started to realise that 'responsive' is not just about scaling your websites to the size of your...

  • By
    Create a Quick MooTools Slideshow with Preloading Images

    I've been creating a lot of slideshow posts lately. Why, you ask? Because they help me get chicks. A quick formula for you: The following code snippet will show you how to create a simple slideshow with MooTools; the script will also...

Discussion

  1. Gabe

    Hmm I like the idea. However, I feel like it would be more useful if external classes couldn’t access the class’s property/variable directly anyway; ‘private’ variables. I do love how this demonstrates the flexibility of Mootools framework.

  2. I implemented something like this some time ago for a custom MVC framework, as you mention a great feature is that you can spy on object properties. My main reason for doing this was for binding my views to property changes. It would be great to implement something like this with event listeners for properties so you could call something like

    myInstance.addEvent('change:value', function(obj, property, value){
      console.log(property + " has changed to: " + value);
    });  
    
  3. Sorry, define[GS]etter are the old deprecated methods. defineProperty is the new version. This is built in to the JavaScript language and provides a familar syntax for properties. Doing blah.value = 123 will call the setter for “value” if you’ve provided one.

    See https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Working_with_Objects#Defining_getters_and_setters

  4. AFAIK none, <= IE8 still has a big chunk of marketshare.

  5. Patrick Welborn

    Thanks for sharing this. Can I use this code as a utility in my MooTools implementations? I like using get/set methods in my programming, and this most mirrors what I have seen in other languages. Seems like it should be part of MooTools More.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!