{"componentChunkName":"component---src-components-posts-layout-index-js","path":"/understanding-closure/","webpackCompilationHash":"6fd724ef40842b910a04","result":{"data":{"mdx":{"id":"52ff7628-ef2c-50e8-9757-5f67da2322c5","timeToRead":3,"body":"function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nfunction _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }\n\nfunction _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }\n\n/* @jsx mdx */\nvar _frontmatter = {\n  \"title\": \"Understanding Closure\",\n  \"date\": \"2020-06-16\",\n  \"excerpt\": \"Closure is a scary word in Javascript. It can feel like an enigma, a secret that is only known by wizards and lab coat wearing computer scientists 🥼🧪. At least that's how I used to feel about it. Turns out, it's not all that spooky, as I will hopefully demonstrate in this post.\"\n};\n\nvar makeShortcode = function makeShortcode(name) {\n  return function MDXDefaultShortcode(props) {\n    console.warn(\"Component \" + name + \" was not imported, exported, or provided by MDXProvider as global scope\");\n    return mdx(\"div\", props);\n  };\n};\n\nvar layoutProps = {\n  _frontmatter: _frontmatter\n};\nvar MDXLayout = \"wrapper\";\nreturn function MDXContent(_ref) {\n  var components = _ref.components,\n      props = _objectWithoutProperties(_ref, [\"components\"]);\n\n  return mdx(MDXLayout, _extends({}, layoutProps, props, {\n    components: components,\n    mdxType: \"MDXLayout\"\n  }), mdx(\"p\", null, \"Closure is a scary word in Javascript. It can feel like an enigma, a secret that is only known by wizards and lab coat wearing computer scientists \\uD83E\\uDD7C\\uD83E\\uDDEA. At least that's how I used to feel about it. Turns out, it's not all that spooky, as I will hopefully demonstrate in this post.\"), mdx(\"br\", null), mdx(\"p\", null, \"First of all, it would be plagiarism to publish this post without giving the proper credit to \", mdx(\"a\", {\n    href: \"https://frontendmasters.com/\"\n  }, \"Front End Masters\"), \". More specifically, the workshop \", mdx(\"a\", {\n    href: \"https://frontendmasters.com/\"\n  }, \"Javascript: The Hard Parts\"), \" led by instructor Will Sentance from \", mdx(\"a\", {\n    href: \"https://www.codesmith.io/\"\n  }, \"Codesmith\"), \". In this post I will distill Will's lesson on Closure into a short, readable format. For the real deal, you should absolutely check out that course as well as the many other great ones on \", mdx(\"a\", {\n    href: \"https://frontendmasters.com/\"\n  }, \"Front End Masters\"), \".  \"), mdx(\"br\", null), mdx(\"h2\", null, \"What is Closure?\"), mdx(\"p\", null, \"Kyle Simpson, author of \", mdx(\"a\", {\n    href: \"https://github.com/getify/You-Dont-Know-JS\"\n  }, \"You Don\\u2019t Know JS\"), \" puts it like this:\"), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"Closure is when a a function \\\"remembers\\\" it's lexical scope even when that function is exexcuted outside of that lexical scope. \", mdx(\"br\", null))), mdx(\"p\", null, \"In other words, we can't understand Closure without first understanding what \\\"lexical scope\\\" is. The good news is that the term \\\"lexical scope\\\" is just another scary sounding word that we can demystify quite easily. \"), mdx(\"br\", null), mdx(\"h2\", null, \"What is Lexical Scope?\"), mdx(\"p\", null, \"Lexical scope is the surrounding environment that a variable or function is defined in. In Javascript, a variable or function is visible to the executing code if it is in the current lexical environment of the enclosing function. \"), mdx(\"p\", null, \"Take a look at this example:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"function outer() {\\n    let counter = 0\\n    function incrementCounter() {\\n        counter++\\n    }\\n    return incrementCounter\\n}\\n\\nlet myNewFunction = outer();\\n// myNewFunction === incrementCounter\\n\\nmyNewFunction()\\n\")), mdx(\"blockquote\", null, mdx(\"p\", {\n    parentName: \"blockquote\"\n  }, \"This is a common pattern in Javascript, storing a function inside another function. The function \", mdx(\"strong\", null, \"outer\"), \" is a \\\"higher order\\\" function because it is returning another function \", mdx(\"strong\", null, \"incrementCounter\"), \".\")), mdx(\"p\", null, \"Intuitively, when looking at the code inside \", mdx(\"strong\", null, \"incrementCounter\"), \" we'd presume that Javscript has no knowledge of the variable \", mdx(\"strong\", null, \"counter\"), \". This is because it is not defined inside of \", mdx(\"strong\", null, \"incrementCounter\"), \". What gives? The Javascript parser initially does look inside of \", mdx(\"strong\", null, \"incrementCounter\"), \" for the variable \", mdx(\"strong\", null, \"counter\"), \". The cool part is that if it doesn't find it inside it's immediate surroundings, it will then look up the \\\"chain\\\" and find counter defined in the enclosing function, in this case \", mdx(\"strong\", null, \"outer\"), \". \"), mdx(\"br\", null), mdx(\"p\", null, \"Because Javascript is lexically scoped, where you define your function determines what variables it has access to when it is executed. Since \", mdx(\"strong\", null, \"incrementCounter\"), \" is defined inside of \", mdx(\"strong\", null, \"outer\"), \" it has access to variables within that enclosing scope. \"), mdx(\"br\", null), mdx(\"p\", null, \"After we define \", mdx(\"strong\", null, \"outer\"), \", we assign it's returned value to \", mdx(\"strong\", null, \"myNewFunction\"), \". As you can see, the returned value of \", mdx(\"strong\", null, \"outer\"), \" is the function \", mdx(\"strong\", null, \"incrementCounter\"), \". To be clear, we are not returning the execution of the function, but the function definition. In other words, the contents of function: \"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"function incrementCounter() {\\n counter++\\n}\\n\\n\")), mdx(\"p\", null, \"Therefore, when we call or \\\"execute\\\" \", mdx(\"strong\", null, \"myNewFunction\"), \", we are really saying \\\"go execute the incrementCounter functionality.\\\" Through the power of closure, when we execute \", mdx(\"strong\", null, \"myNewFunction\"), \", we have access to the surrounding data in it's enclosed environment. In our example, that is the variable \", mdx(\"strong\", null, \"counter\"), \". Since \", mdx(\"strong\", null, \"counter\"), \" is not living inside \", mdx(\"strong\", null, \"incrementCounter\"), \" itself, it's value persists between function calls, making it a live store of data. If \", mdx(\"strong\", null, \"counter\"), \" were to be defined inside of \", mdx(\"strong\", null, \"incrementCounter\"), \", there'd be no way of holding onto it's value and continue updating it. Here's how that would look:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"function outer() {\\n    function incrementCounter() {\\n        let counter = 0\\n        counter++\\n    }\\n    return incrementCounter\\n}\\n\\nlet myNewFunction = outer();\\n\\nmyNewFunction()\\n\")), mdx(\"p\", null, \"In this example, after executing \", mdx(\"strong\", null, \"myNewFunction()\"), \", the counter would be assigned the value of 0, then we'd increment it by 1. On the second call, the same thing would happen. The counter would be assigned the value 0 and then be incremented by 1. Let's take a look at the original example again:\"), mdx(\"pre\", null, mdx(\"code\", _extends({\n    parentName: \"pre\"\n  }, {\n    \"className\": \"language-js\"\n  }), \"function outer() {\\n    let counter = 0\\n    function incrementCounter() {\\n        counter++\\n    }\\n    return incrementCounter\\n}\\n\\nlet myNewFunction = outer();\\n\\nmyNewFunction()\\n\")), mdx(\"p\", null, \"Now, the counter will be preserved on each subsequent execution of \", mdx(\"strong\", null, \"myNewFunction\"), \". On the initial call, counter is assigned the value of 0 as it was set in the enclosing function \", mdx(\"strong\", null, \"outer\"), \". When we invoke \", mdx(\"strong\", null, \"myNewFunction\"), \" we are simply incrementing the counter by 1. The next time \", mdx(\"strong\", null, \"myNewFunction\"), \" is called, the value of counter is what we incremented it to on the first call, 1. Again, we go ahead and increment the counter by 1 and it's value becomes 2. On the subsequent call the value will be 2, then we increment it to 3 and so on. \"), mdx(\"br\", null), mdx(\"p\", null, \"This example clearly demostrates the power of closure. Closure gives our functions memory. With closure, we empower our functions by giving them the ability to \\\"remember\\\" the state of our data. We can keep a live store of data that can be updated each time the function is called.\"), mdx(\"br\", null), mdx(\"p\", null, \"Closure is used everywhere in Javscript. For my fellow react developers out there, check out this \", mdx(\"a\", {\n    href: \"https://www.netlify.com/blog/2019/03/11/deep-dive-how-do-react-hooks-really-work/\"\n  }, \"deep dive\"), \" into how Hooks work under the hood. Spoiler alert: Closure.  \"));\n}\n;\nMDXContent.isMDXComponent = true;","frontmatter":{"title":"Understanding Closure","date":"June 16, 2020"}}},"pageContext":{"isCreatedByStatefulCreatePages":false,"id":"52ff7628-ef2c-50e8-9757-5f67da2322c5","previous":{"id":"43658bb1-e4f8-520e-86ae-5fe72f200715","fields":{"slug":"/implementing-dark-mode/"},"frontmatter":{"title":"Implementing Dark Mode 🌙"}},"next":{"id":"6db09cf7-41c4-5a2c-875b-58c097bd3deb","fields":{"slug":"/coding-career-handbook-review/"},"frontmatter":{"title":"Coding Career Handbook: A review"}}}}}