Dynamic Getters and Setters in Javascript and Coffeescript

Like most developers I make use of dynamic Getters and Setters , whether its the magic methods (_get and _set) in PHP or using MethodMissing in Ruby. These are useful if you want to run some process before setting the data or before getting it, or if you want to get the data from some other data store.

However until recently I hadn’t tried to do this in Javascript. But working on a binding class for a side project , it came apparent that it would be useful to be able to use dynamic getter and setters.

The basic idea of the code was this , it would be a standard JS object but updating the properties of the object it would also update the appropriate part of the html. It is a very similar idea to that of knockout. After reading around on how to do dynamic getter and setters in JS , I came up with the following workflow.

  • The developer registers a binding with the library
  • The developer then adds a data attribute to the html where they want the data to appear
  • The library dynamically creates getters and setters and maps them to the appropriate key in a object literal.
  • When the developer uses <OBJECT>.bar = “foo” the html is updated.

The main point of this workflow as far as getters and setters is that it doesn’t appear to be possible to create a single default dynamic getter and setter , you have to create one for every virtual property that you need. This is more like using the attr_accessor :some_name in ruby. Hence why in the above workflow the first step is simply to register the binding , this allows the code to dynamically set up the getters and setters ready for use.

So how do you create a getter and setter? Well actually it is very easy. Below is the code (in coffee script that creates the getter and setter)

register : (field) ->
    prop = {}
    prop[field] = {}
    prop[field].get = () -> @get(field)
    prop[field].set = (value) -> @set(field, value)

    Object.defineProperties(@ , prop) 

or in plain JS it would look like this

register : function(field) {
  var prop = {};
  prop[field] = {};
  prop[field].get = function() {
    this.get(field);
  };

  prop[field].set = function(value) {
    this.set(field , value);
  };

  Object.defineProperties(this, prop);
}

In both code examples “field” is the name of the property that you are trying to create the getters and setters for and this.get (@.get) and this.set (@.set) are the common functions that carry out getting and setting and any other code required. The bit that actually does the work is the Object.defineProperties method , that takes two arguments the first is the object on which to attach the getter / setters (or other properties) and the second is a object literal containing what to attach. In this case we create the object literal ahead of time so we can use a dynamic name for the property.

We can now use the syntax

some_object.register(“foo”);
some_object.foo = “bar”;
some_object.foo; //=> “bar”

When we use some_object.foo = “bar” then it will call some_object.set(“foo” , “bar”) and likewise some_object.foo will call some_object.get(“foo”). And there you have it dynamic getters and setters in javascript or coffee script.

comments powered by Disqus
Old Yellow Logo

Looking for the old site you can still access it and all its contents at old.dotmh.com