Last Updated: February 25, 2016
·
270
· yannikmesserli

Javascript, redefine unlimited number of setters with same function

Suppose you have an object:

var o = {
    a: 3
    b: 4
}

And you want to save or do something with it whenever a property of this object is changed. This is possible by defining special setters in javascript.

Observe first that means we will need two object: one to actually store the data, one to contain the special getters. (Is there an elegant way to avoid it?)

However, the annoying thing is that - if you read the above API page, setters have to be set by hand. Luckily, Object.defineProperty will help us redefine unlimited number of setters as follow:

var create_custom_setter = function(destination, source, custom_setter){
        destination = destination || {};
        for(var prop in  source){

            if(typeof(source[prop]) === "object"){
                var sub_destination = create_custom_setter({}, source[prop]);
                destination[prop] = sub_destination;
            }else{

                // javascript scope problem:
                var maker_set = function(source, prop){
                    return function(value) {
                        source[prop] = value;
                        custom_setter(value, prop, destination, custom_setter); 
                    }
                }

                // default setter:
                var maker_get  = function(source, prop){
                    return function(){
                        return source[prop];
                    }
                } 

                Object.defineProperty(destination, prop, {
                    set: maker_set(source, prop),
                    get: maker_set(source, prop)
                });
            }
        }
        return destination;
    }

The, I can create a front-facing object of o like this with a custom global setter:

var front_facing = create_custom_setter({}, o, function(value, prop){ 
    console.log(prop + " has been set"); 
})