{"id":10,"date":"2009-06-07T17:28:28","date_gmt":"2009-06-08T01:28:28","guid":{"rendered":"http:\/\/adam.yanalunas.com\/blog\/?p=10"},"modified":"2009-06-07T17:28:28","modified_gmt":"2009-06-08T01:28:28","slug":"yet-another-article-about-closures","status":"publish","type":"post","link":"http:\/\/adam.yanalunas.com\/blog\/archives\/10","title":{"rendered":"Yet another article about closures"},"content":{"rendered":"<h2>\u2026or when variables get too friendly and cause trouble<\/h2>\n<p>JavaScript is a functional language. Because of its functional nature you can do really fun things that may not be readily apparent. One of my favorite things about JavaScript is its implementation of closures, a function complete with its own private scope. Why would that ever be useful? It helps get around one of my least favorite things about JavaScript: scope. A closure is a function that, while it has access to globally-scoped items, has its own, bound local scope. You know those times when you only want a variable to apply to a certain event? No? How about an example?<\/p>\n<p>I bet at first glance you&#8217;ll be able to tell me what this bit of code is supposed to do, but not why it doesn&#8217;t work as expected.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">function addLinks()\r\n{\r\n    for (var i=0, link; i&amp;lt;5; i++)\r\n    {\r\n        link = document.createElement(&quot;a&quot;);\r\n        link.innerHTML = &quot;Link &quot; + i;\r\n        link.onclick = function ()\r\n        {\r\n            alert(i);\r\n        };\r\n        document.body.appendChild(link);\r\n    }\r\n}\r\nwindow.onload = addLinks;<\/pre>\n<p>To be clear, this is a small function that will add five links to the page that read Link 0, Link 1, Link 2, etc. and, when clicked, will pop up an <code>alert<\/code> box with that link&#8217;s number, such as 0, 1, 2, etc. I know appending to the DOM inside a loop is bad practice and that these links are not inside of a block-level entity. For now pretend that these things aren&#8217;t important. What is important is that clicking on any of these links will always <code>alert<\/code> 4 instead of the number belonging to that link.<\/p>\n<h2>Global scope is the enemy of predictability<\/h2>\n<p>As the loop iterates, the variable <code>i<\/code> is being incremented and that number is applied to the individual links as they are made \u2013 so what&#8217;s happening here? JavaScript&#8217;s ultra-friendly, as-global-as-possible scope is stealthily making trouble. For example, if you were to break that loop when <code>i<\/code> was set to 3, for example, all links would <code>alert<\/code> 3.<\/p>\n<p>You see it yet? Exactly. The variable <code>i<\/code> is set in the global sense of the page and each link is referring to the global instance of <code>i<\/code>, not its own local scope. So if I were to run this function then type <code>javascript:i='foo';<\/code> in my address bar each link would <code>alert<\/code> foo. You&#8217;re right to think there has to be a way around this.<\/p>\n<h2>Bringing them together<\/h2>\n<p>So you have a function using a variable but the scope is out of whack? Let&#8217;s see if a closure can help! The trick will be to create a function that only knows what you tell it and make that function what gets called on the <code>onclick<\/code>. If that doesn&#8217;t make sense, read it again and then look at the code. The syntax and execution of closures is fairly counter to most programming techniques so putting yourself in that mindset will take some adjustment. A bit of updated code should help.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">function addLinks()\r\n{\r\n    for (var i=0, link; i&lt;5; i++)\r\n    {\r\n        link = document.createElement(&quot;a&quot;);\r\n        link.innerHTML = &quot;Link &quot; + i;\r\n        link.onclick = function (num)\r\n        {\r\n            return function ()\r\n            {\r\n                alert(num);\r\n            };\r\n        }(i);\r\n        document.body.appendChild(link);\r\n    }\r\n}\r\nwindow.onload = addLinks;<\/pre>\n<p>The <code>onclick<\/code> is now bestowed with a closure and that closure is binding the <code>i<\/code>&#8216;s value into its own local scope so that you can change <code>i<\/code> to be whatever you like and the closure will always remember what it was when you called it. The closure is invoked by the <code>(i)<\/code> at the end of the function, making it a self-invoked function. When it is invoked the <code>i<\/code> is passed in, assigned to the <code>num<\/code> variable which makes it a local, contained variable. Then an anonymous function is returned that will be called when the <code>onclick<\/code> is triggered. That anonymous function doesn&#8217;t have its own <code>num<\/code> variable so it looks up the scope chain, sees one in the <code>onclick<\/code> and uses it.<\/p>\n<p>That last paragraph might need a few passes to fully understand. Don&#8217;t worry, closures are a complicated concept to learn for programmers not well versed in functional languages. In upcoming entries I&#8217;ll talk about stretching JavaScript in two different but powerful ways: lambda functions and exploring public and private variables. Stay tuned!<\/p>\n<p>Recommend reading:<\/p>\n<ul>\n<li><a class=\"popup\" title=\"Functional Javascript\" rel=\"name:www.hunlock.com\" href=\"http:\/\/www.hunlock.com\/blogs\/Functional_Javascript\">http:\/\/www.hunlock.com\/blogs\/Functional_Javascript<\/a><\/li>\n<li><a class=\"poup\" title=\"The Power of Closures - Part 1\" rel=\"name:iablog.sybase.com\" href=\"http:\/\/iablog.sybase.com\/efarrar\/2009\/05\/the-power-of-closures-part-1\/\">http:\/\/iablog.sybase.com\/efarrar\/2009\/05\/the-power-of-closures-part-1\/<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>\u2026or when variables get too friendly and cause trouble JavaScript is a functional language. Because of its functional nature you can do really fun things that may not be readily apparent. One of my favorite things about JavaScript is its implementation of closures, a function complete with its own private scope. Why would that ever [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[],"_links":{"self":[{"href":"http:\/\/adam.yanalunas.com\/blog\/wp-json\/wp\/v2\/posts\/10"}],"collection":[{"href":"http:\/\/adam.yanalunas.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/adam.yanalunas.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/adam.yanalunas.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/adam.yanalunas.com\/blog\/wp-json\/wp\/v2\/comments?post=10"}],"version-history":[{"count":9,"href":"http:\/\/adam.yanalunas.com\/blog\/wp-json\/wp\/v2\/posts\/10\/revisions"}],"predecessor-version":[{"id":19,"href":"http:\/\/adam.yanalunas.com\/blog\/wp-json\/wp\/v2\/posts\/10\/revisions\/19"}],"wp:attachment":[{"href":"http:\/\/adam.yanalunas.com\/blog\/wp-json\/wp\/v2\/media?parent=10"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/adam.yanalunas.com\/blog\/wp-json\/wp\/v2\/categories?post=10"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/adam.yanalunas.com\/blog\/wp-json\/wp\/v2\/tags?post=10"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}