daily pastebin goal
16%
SHARE
TWEET

Untitled

a guest Dec 7th, 2017 52 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. {
  2.  "cells": [
  3.   {
  4.    "cell_type": "markdown",
  5.    "metadata": {},
  6.    "source": [
  7.     "# Closures of incrementor in For Loop. "
  8.    ]
  9.   },
  10.   {
  11.    "cell_type": "code",
  12.    "execution_count": 1,
  13.    "metadata": {},
  14.    "outputs": [],
  15.    "source": [
  16.     "var users = ['Arnie', 'Betty', 'Clarlie', 'Frannie', 'Joey']\n",
  17.     "var guestListFns = function(guests) {\n",
  18.     "    var fns = []\n",
  19.     "    for (var i = 0; i < guests.length; i++) {\n",
  20.     "        var guest = guests[i]\n",
  21.     "        fns.push(function() {\n",
  22.     "            return guest\n",
  23.     "        })\n",
  24.     "    }\n",
  25.     "    return fns\n",
  26.     "}"
  27.    ]
  28.   },
  29.   {
  30.    "cell_type": "code",
  31.    "execution_count": 2,
  32.    "metadata": {},
  33.    "outputs": [],
  34.    "source": [
  35.     "function test() {\n",
  36.     "    var gfns = guestListFns(users)\n",
  37.     "    gfns.forEach(function(fn) {\n",
  38.     "        console.log(fn())\n",
  39.     "    })\n",
  40.     "}\n"
  41.    ]
  42.   },
  43.   {
  44.    "cell_type": "code",
  45.    "execution_count": 3,
  46.    "metadata": {},
  47.    "outputs": [
  48.     {
  49.      "name": "stdout",
  50.      "output_type": "stream",
  51.      "text": [
  52.       "Joey\n",
  53.       "Joey\n",
  54.       "Joey\n",
  55.       "Joey\n",
  56.       "Joey\n"
  57.      ]
  58.     }
  59.    ],
  60.    "source": [
  61.     "test()"
  62.    ]
  63.   },
  64.   {
  65.    "cell_type": "markdown",
  66.    "metadata": {},
  67.    "source": [
  68.     "There is a good reason why 'Joey' is returned everytime.  'guest' points to guests[i] and i is incremented in the for loop and is last modified to hold 'Joey'. Every reference to 'guest' will now resolve to 'Joey'.\n",
  69.     "\n",
  70.     "How can we change this?"
  71.    ]
  72.   },
  73.   {
  74.    "cell_type": "markdown",
  75.    "metadata": {},
  76.    "source": [
  77.     "# Use an IIFE (Immediately Invoked Function Expression)\n",
  78.     "When the JS engine encounters an IIFE, as the name suggests, it will immediately invoke it. \n",
  79.     "The code below the entire body of the for loop is an IIFE which will means the IIFE is executed \n",
  80.     "for each iteration of the loop. What happens next is interesting and solves the reference error/gotcha\n",
  81.     "from above.\n",
  82.     "  1. A new stack frame is created and it closes around variables in scope: (__guests, fns & i__)\n",
  83.     "  2. Space for local variables (__guest__) are allocated.\n",
  84.     "  3. Evaluation/Execution of the IFFE statements begin.\n",
  85.     "\n",
  86.     "This sequence of events will create new local variables that the outer scope can no longer mutate.\n"
  87.    ]
  88.   },
  89.   {
  90.    "cell_type": "code",
  91.    "execution_count": 4,
  92.    "metadata": {},
  93.    "outputs": [
  94.     {
  95.      "name": "stdout",
  96.      "output_type": "stream",
  97.      "text": [
  98.       "Arnie\n",
  99.       "Betty\n",
  100.       "Clarlie\n",
  101.       "Frannie\n",
  102.       "Joey\n"
  103.      ]
  104.     }
  105.    ],
  106.    "source": [
  107.     "guestListFns = function(guests) {\n",
  108.     "    var fns = []\n",
  109.     "    for (var i = 0; i < guests.length; i++) {\n",
  110.     "        // IIFE creates a new stack frame, variables and references through closure\n",
  111.     "        (function() { \n",
  112.     "            var guest = guests[i]\n",
  113.     "            fns.push(function() {\n",
  114.     "                return guest\n",
  115.     "            })            \n",
  116.     "        })()\n",
  117.     "    }\n",
  118.     "    return fns\n",
  119.     "}\n",
  120.     "test()"
  121.    ]
  122.   },
  123.   {
  124.    "cell_type": "markdown",
  125.    "metadata": {},
  126.    "source": [
  127.     "# Use an IIFE with parameters\n",
  128.     "This creates a new memory on the stack that can't be modified by the outer code. Instead of \n",
  129.     "declaring a local variable like the example above, use parameter binding to create the new\n",
  130.     "memory location/reference. Below the iterator i is used as a parameter to the IIFE which gets\n",
  131.     "bound to index within the IIFE. When the IIFE goes out of scope, the anonymous function pushed\n",
  132.     "to fns will have closed around it and retain access."
  133.    ]
  134.   },
  135.   {
  136.    "cell_type": "code",
  137.    "execution_count": 5,
  138.    "metadata": {},
  139.    "outputs": [
  140.     {
  141.      "name": "stdout",
  142.      "output_type": "stream",
  143.      "text": [
  144.       "Arnie\n",
  145.       "Betty\n",
  146.       "Clarlie\n",
  147.       "Frannie\n",
  148.       "Joey\n"
  149.      ]
  150.     }
  151.    ],
  152.    "source": [
  153.     "guestListFns = function(guests) {\n",
  154.     "    var fns = []\n",
  155.     "    for (var i = 0; i < guests.length; i++) {\n",
  156.     "        (function(index) {  \n",
  157.     "            fns.push(function() {\n",
  158.     "                return guests[index]\n",
  159.     "            })            \n",
  160.     "        })(i)  // i is a parameter to IIFE\n",
  161.     "    }\n",
  162.     "    return fns\n",
  163.     "}\n",
  164.     "test()"
  165.    ]
  166.   },
  167.   {
  168.    "cell_type": "markdown",
  169.    "metadata": {},
  170.    "source": [
  171.     "# ES6 Let scoping\n",
  172.     "Let variables are block scoped, and in this case the block is the for-loop body which will be reset for each iteration"
  173.    ]
  174.   },
  175.   {
  176.    "cell_type": "code",
  177.    "execution_count": 6,
  178.    "metadata": {},
  179.    "outputs": [
  180.     {
  181.      "name": "stdout",
  182.      "output_type": "stream",
  183.      "text": [
  184.       "Arnie\n",
  185.       "Betty\n",
  186.       "Clarlie\n",
  187.       "Frannie\n",
  188.       "Joey\n"
  189.      ]
  190.     }
  191.    ],
  192.    "source": [
  193.     "guestListFns = function(guests) {\n",
  194.     "    var fns = []\n",
  195.     "    for (var i = 0; i < guests.length; i++) {\n",
  196.     "        let guest = guests[i]\n",
  197.     "        fns.push(function() {\n",
  198.     "            return guest\n",
  199.     "        })\n",
  200.     "    }\n",
  201.     "    return fns\n",
  202.     "}\n",
  203.     "test()"
  204.    ]
  205.   },
  206.   {
  207.    "cell_type": "code",
  208.    "execution_count": null,
  209.    "metadata": {},
  210.    "outputs": [],
  211.    "source": []
  212.   }
  213.  ],
  214.  "metadata": {
  215.   "kernelspec": {
  216.    "display_name": "Javascript (Node.js)",
  217.    "language": "javascript",
  218.    "name": "javascript"
  219.   },
  220.   "language_info": {
  221.    "file_extension": ".js",
  222.    "mimetype": "application/javascript",
  223.    "name": "javascript",
  224.    "version": "8.9.1"
  225.   }
  226.  },
  227.  "nbformat": 4,
  228.  "nbformat_minor": 2
  229. }
RAW Paste Data
Top