Javascript Closures

I had an ‘ah ha!’ moment regarding closures yesterday. I had seen videos from some of the best minds in Computer Science explaining the intricacies of scope in functions. I had received lessons from Sean at The Iron Yard regarding this and how variables are seen or not seen by functions as well as as discussing closures, specifically. I thought I understood!

Then, yesterday, I was told to pull the API calls out of the functions I had written and tack them onto an api object as methods. I am told that this will enable the functions to be used outside of the browser, but I don’t know exactly what that means in terms of implementation yet. Nonetheless, I set out to accomplish the task I had been given. I created the first without any trouble:

var api = {
records: {}
, domains: {}
, devices: {}
};

api.records.list = function () {
return somePromise({
url: 'https://somesite.com/' + session.token.sub + '/dns'
, method: 'GET'
, session: session
}, {}).then(function (res) {
return res.data
});
};

No problem. Replaced my function with api.records.list and tested. Fired right up as expected. Okay, I got this, a few more just like that and I’m starting to actually feel like this is ‘too’ easy. Then I run into this function:

api.domains.nsList = function () {
return somePromise({
url: 'https://somesite.com/' + session.token.sub + '/ns' + '/' + tld + '/' + sld + '/' + sub
, method: 'GET'
, session: session
}, {}).then(function (res) {
return res.data
});
};

Okay easy enough, right! Run the test… Boom! ERROR!

tld is undefined

Excuse me? tld IS defined! It’s right there inside the function that I’ve wrapped around this API call. It’s actually two lines above where I’m executing the function that should be consuming it! Luckily I’ve got my co-worker Seth in the office behind me so after a few different attempts and some increasingly unhelpful error messages, I tap him on the shoulder and describe the situation. He says “You should look up some documentation on JavaScript closures.” I think to myself… ‘I’ve spent several hours with documentation on JavaScript closures. What am I missing here?’

I wish I could quote him on what he said exactly, but I instantly understood the point of Sean’s lessons about this and Douglas Crockford’s lecture on lexical scoping and closures. Something like:

“When you declare a function outside of another function, it doesn’t have access to variables declared within the function that calls it.”

He probably thought I was crazy with the huge smile that spread across my face as I finally encountered this fundamental concept of Functional Programming in JS. It took me no time at all to edit my function to:

api.domains.nsList = function (record) {
var tld = record.tld;
var sld = record.sld;
var sub = record.sub || '';

return OAUTH3.request({
return somePromise({
url: 'https://somesite.com/' + session.token.sub + '/ns' + '/' + tld + '/' + sld + '/' + sub
, method: 'GET'
, session: session
}, {}).then(function (res) {
return res.data
});
};

And that’s the story of the first time I consciously and intentionally manipulated lexical scope to write a closure in JavaScript! Feels good.

A single golf clap? Or a long standing ovation?

By clapping more or less, you can signal to us which stories really stand out.