I'm having some trouble wrapping my mind around javascript functional programming patterns, specifically as they relate to variable scopes. Much of what I've been able to find on the subject online has been helpful; but things still aren't clicking. Consider the following example:
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="/d3.v3.min.js"></script>
</head>
<body>
<script type="text/javascript">
function SimpleWidget(spec) {
var instance = {};
var headline, description;
instance.render = function () {
var div = d3.select('body').append("div");
div.append("h3").text(headline);
div.attr("class", "box")
.attr("style", "color:" + spec.color)
.append("p")
.text(description);
return instance;
};
instance.headline = function (h) {
if (!arguments.length) return headline;
headline = h;
return instance;
};
instance.description = function (d) {
if (!arguments.length) return description;
description = d;
return instance;
};
return instance;
}
var widget = SimpleWidget({color: "#6495ed"})
.headline("Simple Widget")
.description("This is a simple widget demonstrating functional javascript.");
widget.render();
</script>
</body>
</html>
This pattern is useful as it encapsulates a reusable snippet of code. We could refactor the SimpleWidget() function to take in an element id, and update the render function with some simple jquery code to update the dom, and thus be able to use it to update any given element. Useful, but I don't have a solid understanding of how it works.
How does the widget object have access to the passed in variable 'spec' ({color: "#6495ed"})? Looking at the method chaining, I would expect 'widget' to simply have 3 functions, but it somehow has access to the inner scope variables of the simpleWidget() function as well.
Running this through the chrome debugger shows that the render function inside the widget object has a 'function scope' which holds the description, instance, and spec variables; but this seems to happen magically. I'm not clear on how these inner variables are being passed around when assigning their containing function to a variable, and subsequently calling it's functions.
What particularly boggles my mind is how the render() function is able to access the spec variable, when both the headline and description functions return the instance object. I'm hoping someone can point me in the right direction here.