I recently found a document by Mike Bostock, Towards Reusable Charts, which describes some conventions for encapsulating reusable charts in D3. Note however that the question isn't just about D3 but rather creating methods for JavaScript objects dynamically.
His proposal includes the following snippet:
function chart() {
var width = 720, // default width
height = 80; // default height
function my() {
// generate chart here, using `width` and `height`
}
my.width = function(value) {
if (!arguments.length) return width;
width = value;
return my;
};
my.height = function(value) {
if (!arguments.length) return height;
height = value;
return my;
};
return my;
}
This is all fine but what I am immediately wondering once I started adding more chart properties than just width
and height
to it is whether the common parts of these "property accessor functions" could be factored out somehow.
I am imagining some method to dynamically register a property like this:
my.addProperty(propName) {
my[propName] = function (value) {
if (!arguments.length) return getPrivateVar(propName);
setPrivateVar(propName, value);
return my;
};
}
So I could then simply do
my.addProperty('width');
my.addProperty('height');
to achieve the same result as the my.width =
and my.height =
statements from the code above.
Is this even possible? How?
EDIT:
The crux of the matter is obviously accessing the "private" variables width
and height
of the chart()
function by name (represented by the get/setPrivateVar()
method calls inside my addProperty
idea). Therefore, answers to this related question (which focus on getting a global variable by name) obviously won't work.