Advertisement
Guest User

Untitled

a guest
Apr 22nd, 2019
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 8.07 KB | None | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3.  
  4. <head>
  5.     <meta charset="UTF-8">
  6.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7.     <meta http-equiv="X-UA-Compatible" content="ie=edge">
  8.     <title>Document</title>
  9.     <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/styles/darcula.min.css">
  10.     <script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.6/highlight.min.js"></script>
  11.     <link rel="stylesheet" type="text/css" href="style2.css">
  12. </head>
  13.  
  14. <body>
  15.     <section class="header">
  16.         <h1>A <span class="yellow">BraveDuck</span> Adventure</h1>
  17.         <h4>Into Closures</h4>
  18.     </section>
  19.  
  20.     <section class="content">
  21.         <h1>Functions within functions</h1>
  22.         <p class="quote" data-who="- Some Wordy Pants">A closure is formed when an <em>outer</em> function encloses an
  23.             <em>inner function</em>, and that inner function accesses the variables defined in the enclosing function's
  24.             scope after the enclosing function has finished invoking.</p>
  25.         <p>Now, I love word-salad as much as the next fellow, but that's a heap and a half to understand if we're only
  26.             just learning about function scopes.</p>
  27.         <p>So, rather than focusing on whether we can <em>talk the talk</em> let's just go walk the walk with a bit of
  28.             code.</p>
  29.         <h2>The humble returnStr function</h2>
  30.         <p>Observe the following very simplistic function. It accepts a single parameter str, and returns that
  31.             parameter without doing anything else.</p>
  32.         <pre><code>
  33.                 function returnStr(str) {
  34.                     return str;
  35.                 }
  36.                 console.log(returnStr("BraveDuck")) // prints 'BraveDuck'
  37.             </code></pre>
  38.         <p>So far so good: However, let's now modify our returnStr function. Now, instead of returning the <em>str
  39.                 parameter</em> the function will return a new <em>function definition</em> which then returns str.</p>
  40.  
  41.  
  42.  
  43.         <pre><code>
  44.                 function returnStr(str) {
  45.                     return function() {
  46.                         return str;
  47.                     }
  48.                 }
  49.                 // definitely does not print 'BraveDuck'
  50.                 console.log(returnStr("BraveDuck"))
  51.         </code></pre>
  52.  
  53.         <p>So, what happens? The important thing to note is that when we <em>Invoke returnStr</em> we get <em>a new
  54.                 function definition</em> which is <b>not</b> automatically invoked.</p>
  55.         <p>So, if we wanted to return to a point where our function correctly printed <em>str</em> we could immediately
  56.             invoke the newly returned function.</p>
  57.         <pre><code>
  58.             function returnStr(str) {
  59.                 return function() {
  60.                     return str;
  61.                 }
  62.             }
  63.             //notice: the double function call inside the console log.
  64.             console.log(returnStr("BraveDuck")());
  65.         </code></pre>
  66.     </section>
  67.     <section class="content">
  68.         <h1>Further illustrating the point of returning a function definition</h1>
  69.         <p>To further illustrate the point of returning a function definition, let's try to break it into a few more
  70.             steps.</p>
  71.         <em>We utilize the following knowledge:</em>
  72.         <ul>
  73.             <li>variables can store anything, even functions.</li>
  74.             <li>a function stored in a variable can be invoked later.</li>
  75.         </ul>
  76.  
  77.         <pre><code>
  78.             function returnStr(str) {
  79.                 return function() {
  80.                     return str;
  81.                 }
  82.             }
  83.  
  84.             var savedMethod1 = returnStr('BraveDuck');
  85.             var savedMethod2 = returnStr('BraveReader');
  86.         </code></pre>
  87.         <p>Okay, so in the above snippet, we call returnStr twice and store the <em>function definition</em> returned by
  88.             returnStr in savedMethod1 and savedMethod2.</p>
  89.         <p>Note: we invoked the method with two different text strings. BraveDuck, and BraveReader.</p>
  90.         <p>Because the function returned from returnStr exists inside a <em>closure</em> of returnStr, it still holds a
  91.             reference to the specific value of <em>str</em></p>
  92.         <p>So now when we invoke either savedMethod1, or savedMethod2, it returns the "memorized" string from when those
  93.             methods were defined.</p>
  94.         <pre><code class="js">
  95.                 console.log(savedMethod1()); //prints 'BraveDuck'
  96.                 console.log(savedMethod2()); //prints 'BraveReader'
  97.         </code></pre>
  98.         <p>So as seen from the snippet we are now able to print both BraveDuck and BraveReader without ever referencing
  99.             the <em>str</em> parameter directly in our print statement.</p>
  100.     </section>
  101.     <section class="content">
  102.         <h1>Lets add a bit more complexity</h1>
  103.         <p>Now that we have seen that its possible to create a "closure" by returning a function definition and saving
  104.             it, we'll add a little more complexity.</p>
  105.         <p>Observe the following code, which returns a new function that will repeat a text.</p>
  106.         <pre><code>
  107.         function numberRepeater(times) {
  108.             return function(text) {
  109.                 let repeatedText = "";
  110.                 for(let i = 0; i &lt; times; i++) {
  111.                     repeatedText += text;
  112.                 }
  113.                 return repeatedText;
  114.             }
  115.         }
  116.     </code></pre>
  117.         <p>Now this example is fairly similar to the previous one, with one notable example of an added parameter to the
  118.             <em>inner function</em>.</p>
  119.         <p>The point that might be a bit confusing at this part if you are unused to reading code is understanding where
  120.             <em>text</em> is defined</p>
  121.         <p>The answer, simply put is: Later.</p>
  122.         <p>Because <em>numberRepeater</em> is returning a <em>function definition</em> we can give this function a
  123.             parameter, exactly as if we were writing a function normally, and then, when we invoke this returned
  124.             function definition later. That is when <em>text</em> is defined.</p>
  125.         <pre><code class="js">
  126.         //print hello 3 times by immediately invoking the returned inner function.
  127.         numberRepeater(3)("hello"); //print 'hellohellohello';
  128.     </code></pre>
  129.         <p>Now to break it up into a few more steps, let's use our <em>numberRepeater</em> function to make a new
  130.             function that always repeats a text 5 times.</p>
  131.         <pre><code>
  132.         const repeatFive = numberRepeater(5);
  133.     </code></pre>
  134.         <p>Because repeatFive is not immediately invoked, the function definition gets saved to <em>repeatFive</em> in a
  135.             closure with a reference to times instantiated to the value 5.</p>
  136.         <pre><code class="js">
  137.         // prints 'BraveDuckBraveDuckBraveDuckBraveDuckBraveDuck'
  138.         repeatFive('BraveDuck');
  139.         // prints 'SnuggumsSnuggumsSnuggumsSnuggumsSnuggums'
  140.         repeatFive('Snuggums');
  141.     </code></pre>
  142.         <p>and the full code listing looks as follows:</p>
  143.         <pre><code>
  144.             function numberRepeater(times) {
  145.                 return function(text) {
  146.                     let repeatedText = "";
  147.                     for(let i = 0; i &lt; times; i++) {
  148.                         repeatedText += text;
  149.                     }
  150.                     return repeatedText;
  151.                 }
  152.             }
  153.  
  154.             numberRepeater(3)("hello");
  155.             const repeatFive = numberRepeater(5);
  156.             repeatFive('BraveDuck');
  157.             repeatFive('Snuggums');
  158.     </code></pre>
  159.     <p>With this we can begin to see the potential of closures being able to refer to the variables of their parent scope, even after the outer function has finished being invoked.</p>
  160.     </section>
  161.     <section class="content sign-off">
  162.         I hope this write-up has been useful to you. Thanks for reading.
  163.     </section>
  164.     <script>
  165.         hljs.initHighlighting();
  166.         console.log(hljs);
  167.     </script>
  168. </body>
  169.  
  170. </html>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement