{"id":706,"date":"2019-08-23T02:10:44","date_gmt":"2019-08-23T02:10:44","guid":{"rendered":"http:\/\/www.projectimmerse.com\/blog\/?p=706"},"modified":"2020-07-13T09:34:13","modified_gmt":"2020-07-13T09:34:13","slug":"javascript-closures","status":"publish","type":"post","link":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/","title":{"rendered":"Javascript Closures"},"content":{"rendered":"\r\n<p>Yeah. Closures. I know I&#8217;m kind of late in getting to this. Closures have been widely discussed subject among developers and I feel like I should get a good handle on it myself. First things first though, it&#8217;s important to understand that closures in javascript are a feature not a built in construct. If you&#8217;ve been writing in Javascript you&#8217;ve already encountered closures you just weren&#8217;t aware of it. I think the concept of closures tends to intimidate or confuse a lot of beginners and even self proclaimed experts in javascript.<\/p>\r\n\r\n<!--more-->\r\n\r\n<p>Another important thing to note is that Javascript in ES6 has rolled out with some new constructs to tackle this complexity. Namely, the <strong>&#8216;let&#8217;<\/strong> keyword has allowed for more control over scope and <strong>arrow functions<\/strong> which provide a concise approach to writing anonymous functions.<\/p>\r\n\r\n<p>I would like to give credit to <a href=\"https:\/\/www.youtube.com\/user\/techSithTube\" title=\"TechSith Youtube Channel\">TechSith<\/a> for making it easy to understand closures. I&#8217;ve watched and read so many online tutorials and they just don&#8217;t seem to explain it very well &#8211; if anything I found myself a little more confused each time. So let&#8217;s dive in.<\/p>\r\n\r\n<h2>Lexical Scope<\/h2>\r\n<p>Lexical scoping in javascript is a term to describe how variables defined outside a function are available in other functions in the program, without even passing them as arguments. Let&#8217;s check out a super simple example below:<\/p>\r\n\r\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nlet i = 1;\r\n\r\nconst f = () =&gt; {\r\n        console.log(i);\r\n}\r\n\r\nf(); \/\/ output: 1\r\n\r\n<\/pre>\r\n\r\n<p>We see that the variable &#8220;i&#8221; is never passed to our declared f() function &#8211; however when we invoke the function it outputs &#8220;1&#8221;. How is this possible? Well this is one of Javascript&#8217;s really weird parts and if you aren&#8217;t paying attention to how you write your programs this can throw you off. Here though &#8211; we are already making use of &#8220;closures, it&#8217;s really hard to notice though.<\/p>\r\n\r\n<p>The key thing to understand is that the &#8220;i&#8221; variable which contains the value &#8220;1&#8221; is available everywhere. This is because the &#8220;i&#8221; variable is attached to the outermost window object.<\/p>\r\n\r\n<p>But things start getting a little tricky when we start moving things around. Let&#8217;s check out another case below:<\/p>\r\n\r\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nif (true) {\r\n        let i = 1;\r\n\r\n        const f = () =&gt; {\r\n                console.log(i);\r\n        }\r\n\r\n}\r\n\r\nf(); \/\/ ReferenceError: f is not defined\r\n\r\n<\/pre>\r\n\r\n<p>Yup we get an reference error when the program is run. This is because &#8220;i&#8221; is defined inside of a block scope, in this case inside an if statement. So how do we fix this? Well, we can define the function <strong>f()<\/strong> outside the <strong>if conditional<\/strong><\/p>\r\n\r\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nlet f;\r\n  \r\nif (true) {\r\n        let i = 1;\r\n\r\n        f = () =&gt; {\r\n                console.log(i);\r\n        }\r\n\r\n}\r\n\r\nf(); \/\/ outputs 1\r\n\r\n<\/pre>\r\n\r\n<p>Okay so by initially declaring &#8220;f&#8221; outside the if block, we&#8217;ve made the &#8220;i&#8221; variable available within the if scope. Being lexically aware where our functions and variables are declared has really helped me keep track and avoid any confusion when writing out my programs.<\/p>\r\n\r\n<p>Okay so far we&#8217;ve been attaching everything to the global scope, so a closure is hardly noticeable. Let&#8217;s make this more obvious by working inside a function declaration. See the example below.<\/p>\r\n\r\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nfor (let i = 0; i &lt; 3; i++) {\r\n\r\n        setTimeout(\r\n                () =&gt; {\r\n                        console.log(i);\r\n                }, 1000);\r\n\r\n}\r\n\r\n\/\/ outputs 0, 1, 2\r\n\r\n<\/pre>\r\n\r\n<p>Well that&#8217;s great thanks to the &#8216;let&#8217; keyword introduced in ES6. But what if we changed &#8216;let&#8217; to &#8216;var&#8217;, we get a different result.<\/p>\r\n\r\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\r\nfor (var i = 0; i &lt; 3; i++) {\r\n\r\n        setTimeout(\r\n                () =&gt; {\r\n                        console.log(i);\r\n                }, 1000);\r\n\r\n}\r\n\r\n\/\/ outputs 3, 3, 3\r\n\r\n<\/pre>\r\n\r\n<p>Okay so we aren&#8217;t getting the result we expected. Why though? It shouldn&#8217;t even be going up to the 3 at all.<\/p>\r\n\r\n<p>Well the answer to this lies in how the <strong>var<\/strong> keyword behaves compared to the <strong>let<\/strong> keyword. The <strong>var<\/strong> keyword is functionally scope whereas the <strong>let<\/strong> keyword is block scoped. And so when we use <strong>var<\/strong> in a loop construct, a new variable isn&#8217;t created, it&#8217;s the value that changes. However, when using the <strong>let<\/strong> variable, each variable AND value is updated and so we get three separate values for &#8220;i&#8221;<\/p>\r\n\r\n<p>I hope this post has helped you better understand closures, I know it has for me. Reviewing lexical scope, block scope and function scope can additionally help you understand how closures work. I&#8217;ll cover these topics in a future post. Until then, keep immersing yourself into anything you want to learn!<\/p> \r\n\r\n\r\n","protected":false},"excerpt":{"rendered":"<p>Yeah. Closures. I know I&#8217;m kind of late in getting to this. Closures have been widely discussed subject among developers and I feel like I should get a good handle on it myself. First things first though, it&#8217;s important to understand that closures in javascript are a feature not a built in construct. If you&#8217;ve &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Javascript Closures&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":1103,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-706","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.3 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Javascript Closures - Project Immerse<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Javascript Closures - Project Immerse\" \/>\n<meta property=\"og:description\" content=\"Yeah. Closures. I know I&#8217;m kind of late in getting to this. Closures have been widely discussed subject among developers and I feel like I should get a good handle on it myself. First things first though, it&#8217;s important to understand that closures in javascript are a feature not a built in construct. If you&#8217;ve &hellip; Continue reading &quot;Javascript Closures&quot;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/\" \/>\n<meta property=\"og:site_name\" content=\"Project Immerse\" \/>\n<meta property=\"article:published_time\" content=\"2019-08-23T02:10:44+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2020-07-13T09:34:13+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2019\/08\/javascript-closures-1.png\" \/>\n\t<meta property=\"og:image:width\" content=\"750\" \/>\n\t<meta property=\"og:image:height\" content=\"750\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"projectimmerse\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"projectimmerse\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/\"},\"author\":{\"name\":\"projectimmerse\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/#\\\/schema\\\/person\\\/c53f2864be524ee6fa08a7e4800dd1e5\"},\"headline\":\"Javascript Closures\",\"datePublished\":\"2019-08-23T02:10:44+00:00\",\"dateModified\":\"2020-07-13T09:34:13+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/\"},\"wordCount\":728,\"commentCount\":0,\"image\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/08\\\/javascript-closures-1.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/\",\"url\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/\",\"name\":\"Javascript Closures - Project Immerse\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/08\\\/javascript-closures-1.png\",\"datePublished\":\"2019-08-23T02:10:44+00:00\",\"dateModified\":\"2020-07-13T09:34:13+00:00\",\"author\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/#\\\/schema\\\/person\\\/c53f2864be524ee6fa08a7e4800dd1e5\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/08\\\/javascript-closures-1.png\",\"contentUrl\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/wp-content\\\/uploads\\\/2019\\\/08\\\/javascript-closures-1.png\",\"width\":750,\"height\":750,\"caption\":\"Javascript Closures\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/javascript-closures\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Javascript Closures\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/\",\"name\":\"Project Immerse\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/#\\\/schema\\\/person\\\/c53f2864be524ee6fa08a7e4800dd1e5\",\"name\":\"projectimmerse\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g\",\"caption\":\"projectimmerse\"},\"url\":\"https:\\\/\\\/www.projectimmerse.com\\\/blog\\\/author\\\/projectimmerse\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Javascript Closures - Project Immerse","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/","og_locale":"en_US","og_type":"article","og_title":"Javascript Closures - Project Immerse","og_description":"Yeah. Closures. I know I&#8217;m kind of late in getting to this. Closures have been widely discussed subject among developers and I feel like I should get a good handle on it myself. First things first though, it&#8217;s important to understand that closures in javascript are a feature not a built in construct. If you&#8217;ve &hellip; Continue reading \"Javascript Closures\"","og_url":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/","og_site_name":"Project Immerse","article_published_time":"2019-08-23T02:10:44+00:00","article_modified_time":"2020-07-13T09:34:13+00:00","og_image":[{"width":750,"height":750,"url":"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2019\/08\/javascript-closures-1.png","type":"image\/png"}],"author":"projectimmerse","twitter_card":"summary_large_image","twitter_misc":{"Written by":"projectimmerse","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/#article","isPartOf":{"@id":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/"},"author":{"name":"projectimmerse","@id":"https:\/\/www.projectimmerse.com\/blog\/#\/schema\/person\/c53f2864be524ee6fa08a7e4800dd1e5"},"headline":"Javascript Closures","datePublished":"2019-08-23T02:10:44+00:00","dateModified":"2020-07-13T09:34:13+00:00","mainEntityOfPage":{"@id":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/"},"wordCount":728,"commentCount":0,"image":{"@id":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/#primaryimage"},"thumbnailUrl":"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2019\/08\/javascript-closures-1.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/","url":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/","name":"Javascript Closures - Project Immerse","isPartOf":{"@id":"https:\/\/www.projectimmerse.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/#primaryimage"},"image":{"@id":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/#primaryimage"},"thumbnailUrl":"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2019\/08\/javascript-closures-1.png","datePublished":"2019-08-23T02:10:44+00:00","dateModified":"2020-07-13T09:34:13+00:00","author":{"@id":"https:\/\/www.projectimmerse.com\/blog\/#\/schema\/person\/c53f2864be524ee6fa08a7e4800dd1e5"},"breadcrumb":{"@id":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/#primaryimage","url":"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2019\/08\/javascript-closures-1.png","contentUrl":"https:\/\/www.projectimmerse.com\/blog\/wp-content\/uploads\/2019\/08\/javascript-closures-1.png","width":750,"height":750,"caption":"Javascript Closures"},{"@type":"BreadcrumbList","@id":"https:\/\/www.projectimmerse.com\/blog\/javascript-closures\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.projectimmerse.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Javascript Closures"}]},{"@type":"WebSite","@id":"https:\/\/www.projectimmerse.com\/blog\/#website","url":"https:\/\/www.projectimmerse.com\/blog\/","name":"Project Immerse","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.projectimmerse.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/www.projectimmerse.com\/blog\/#\/schema\/person\/c53f2864be524ee6fa08a7e4800dd1e5","name":"projectimmerse","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/4d06955033d6227bfdcf30014e457e4334f7deeb73907de49b65ec2484921931?s=96&d=mm&r=g","caption":"projectimmerse"},"url":"https:\/\/www.projectimmerse.com\/blog\/author\/projectimmerse\/"}]}},"_links":{"self":[{"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/posts\/706","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/comments?post=706"}],"version-history":[{"count":28,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/posts\/706\/revisions"}],"predecessor-version":[{"id":1203,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/posts\/706\/revisions\/1203"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/media\/1103"}],"wp:attachment":[{"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/media?parent=706"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/categories?post=706"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.projectimmerse.com\/blog\/wp-json\/wp\/v2\/tags?post=706"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}