Dynamic getter/setter generation

Tired of writing a getter/setter for every variable in your D3 components? Give this trick a shot.

JavaScript

/*
 * Dynamic getter/setter generation example!
 * 
 * Idea by Rory Hardy [GneatGeek]
 */

viz = window.viz || {};

/**
 * getSet creates a getter/setter function for a re-usable D3.js component. 
 *
 * @method getSet
 * @param  {string}   option    - the name of the object in the string you want agetter/setter for.
 * @param  {function} component - the D3 component this getter/setter relates to.
 *
 * @return {mixed} The value of the option or the component.
 */
function getSet(option, component) {
    return function (_) {
        if (! arguments.length) {
            return this[option];
        }

        this[option] = _;

        return component;
    };
}

(function () {
    viz.bar = function () {
        var opts = {
            width  : 200,
            height : 50,
            color  : '#000'
        };

        function bar(svg) {
            svg.append('rect')
                .attr('width',  opts.width)
                .attr('height', opts.height)
                .attr('fill',   opts.color);
        }

        /* 
         * Loop over all the values in opts to create a getter and setter dynamically.
         * Bind the opts object to each getter/setter function.
         * Note, opts becomes this in the getter/setter function
         */
        for (var key in opts) {
            bar[key] = getSet(key, bar).bind(opts);
        }

        return bar;
    };
}());

/* 
 * Add a function call of color to bar. Works right?
 * Now add one for ratio. Oops, console error right?
 * Add ratio as a value in the opts object. You'll find the error went away.
 * That's the goal, if I declare it, I have a getter and setter immediately!
 *
 * Note that no getter/setter functions were manually written for these functions
 */
var bar = viz.bar()
    .width(350)
    .height(30);

d3.select('body')
    .append('svg')
    .call(bar);