Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scope & Closures in JavaScript

Scope & Closures in JavaScript

A deep dive into Scope & Closures in JavaScript.
Presented at the BeerJS Meetup in September, 2018.

Luciano Battagliero

September 20, 2018
Tweet

More Decks by Luciano Battagliero

Other Decks in Programming

Transcript

  1. var y = 40; function foo() { var x =

    2; return x + y; } foo();
  2. var y = 40; function foo() { var x =

    2; return x + y; } foo(); // → 42
  3. var y = 40; function foo() { var x =

    2; return x + y; } foo(); // → 42
  4. var y = 40; function foo() { var x =

    2; return x + y; } foo(); // → 42
  5. var y = 40; function foo() { var x =

    2; return x + y; } foo(); // → 42
  6. var x = 'tree'; function foo() { var x =

    'shadow'; return x; } foo();
  7. var x = 'tree'; function foo() { var x =

    'shadow'; return x; } foo(); // → shadow
  8. var x = 'tree'; function foo() { var x =

    'shadow'; return x; } foo(); // → shadow
  9. var x = 'tree'; function foo() { var x =

    'shadow'; return x; } foo(); // → shadow
  10. function foo() { var x = 2; return x +

    y; } foo(); // → ReferenceError: y is not defined
  11. function foo() { var x = 2; return x +

    y; } foo(); // → ReferenceError: y is not defined
  12. function foo() { var x = 2; return x +

    y; } foo(); // → ReferenceError: y is not defined
  13. function foo() { var x = 2; return x +

    y; } foo(); // → ReferenceError: y is not defined
  14. function getGlobal() { if (typeof self !== 'undefined') { return

    self; } if (typeof window !== 'undefined') { return window; } if (typeof global !== 'undefined') { return global; } throw new Error('Unable to locate global object'); };
  15. var x = 'tree'; function foo() { var x =

    'shadow'; return x; } foo();
  16. var x = 'tree'; function foo() { var x =

    'shadow'; return x; } foo(); // → shadow
  17. var x = 'tree'; function foo() { var x =

    'shadow'; return window.x; } foo();
  18. var x = 'tree'; function foo() { var x =

    'shadow'; return window.x; } foo(); // → tree
  19. function foo() { var x = 42; console.log(x); // →

    42 }; foo(); console.log(x); // → ReferenceError
  20. function foo() { var x = 42; console.log(x); // →

    42 }; foo(); console.log(x); // → ReferenceError
  21. function foo() { var x = 42; console.log(x); // →

    42 }; foo(); console.log(x); // → ReferenceError
  22. function foo() { var x = 42; console.log(x); // →

    42 }; foo(); console.log(x); // → ReferenceError
  23. function foo() { var x = 42; console.log(x); // →

    42 }; foo(); console.log(x); // → ReferenceError
  24. (function () { var x = 42; console.log(x); // →

    42 })(); console.log(x); // → ReferenceError
  25. (function () { var x = 42; console.log(x); // →

    42 })(); console.log(x); // → ReferenceError
  26. (function () { var x = 42; console.log(x); // →

    42 })(); console.log(x); // → ReferenceError
  27. (function () { var x = 42; console.log(x); // →

    42 })(); console.log(x); // → ReferenceError
  28. (function () { var x = 42; console.log(x); // →

    42 })(); console.log(x); // → ReferenceError
  29. if (true) { var x = 42; console.log(x); // →

    42 } console.log(x); // → 42
  30. if (true) { var x = 42; console.log(x); // →

    42 } console.log(x); // → 42
  31. if (true) { var x = 42; console.log(x); // →

    42 } console.log(x); // → 42
  32. if (true) { var x = 42; console.log(x); // →

    42 } console.log(x); // → 42
  33. if (true) { var x = 42; console.log(x); // →

    42 } console.log(x); // → 42
  34. // “Under the hood” var x; if (true) { x

    = 42; console.log(x); } console.log(x);
  35. // “Under the hood” var x; if (true) { x

    = 42; console.log(x); // → 42 } console.log(x); // → 42
  36. // “Under the hood” var x; if (true) { x

    = 42; console.log(x); } console.log(x);
  37. // “Under the hood” var x; if (true) { x

    = 42; console.log(x); // → 42 } console.log(x); // → 42
  38. try { throw 42; } catch(x) { console.log(x); // →

    42 } console.log(x); // → ReferenceError
  39. try { throw 42; } catch(x) { console.log(x); // →

    42 } console.log(x); // → ReferenceError
  40. try { throw 42; } catch(x) { console.log(x); // →

    42 } console.log(x); // → ReferenceError
  41. try { throw 42; } catch(x) { console.log(x); // →

    42 } console.log(x); // → ReferenceError
  42. try { throw 42; } catch(x) { console.log(x); // →

    42 } console.log(x); // → ReferenceError
  43. if (true) { let x = 42; console.log(x); // →

    42 } console.log(x); // → ReferenceError
  44. { let x = 42; console.log(x); // → 42 }

    console.log(x); // → ReferenceError
  45. function foo() { return 2; } foo(); // → 4

    function foo() { return 4; }
  46. // “Under the hood” function foo() { return 2; }

    function foo() { return 4; } foo();
  47. // “Under the hood” function foo() { return 2; }

    function foo() { return 4; } foo(); // → 4
  48. function foo() { return 2; } foo(); // → 2

    var foo = function () { return 4; };
  49. // “Under the hood” function foo() { return 2; }

    var foo; foo(); foo = function () { return 4; };
  50. // “Under the hood” function foo() { return 2; }

    var foo; foo(); // → 2 foo = function () { return 4; };
  51. foo(); // → TypeError: foo is not a function var

    foo = function () { return 42; };
  52. // “Under the hood” var foo; foo(); // → TypeError:

    foo is not a function foo = function () { return 42; };
  53. function foo() { let x = 42; return function ()

    { console.log(x); }; } let bar = foo(); bar(); console.log(x);
  54. function foo() { let x = 42; return function ()

    { console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
  55. function foo() { let x = 42; return function ()

    { console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
  56. function foo() { let x = 42; return function ()

    { console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
  57. function foo() { let x = 42; return function ()

    { console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
  58. function foo() { let x = 42; return function ()

    { console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
  59. function foo() { let x = 42; return function ()

    { console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
  60. function foo() { let x = 42; return function ()

    { console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
  61. let x = 'FOO_SCOPE'; function foo() { console.log(x); } function

    bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo);
  62. let x = 'FOO_SCOPE'; function foo() { console.log(x); } function

    bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
  63. let x = 'FOO_SCOPE'; function foo() { console.log(x); } function

    bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
  64. let x = 'FOO_SCOPE'; function foo() { console.log(x); } function

    bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
  65. let x = 'FOO_SCOPE'; function foo() { console.log(x); } function

    bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
  66. let x = 'FOO_SCOPE'; function foo() { console.log(x); } function

    bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
  67. let x = 'FOO_SCOPE'; function foo() { console.log(x); } function

    bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
  68. // “Deep down in the JavaScript Engine” function setTimeout(callback, delay)

    { // Works using magic! isItTimeAlready(delay) && callback(); }
  69. // “Deep down in the JavaScript Engine” function setTimeout(callback, delay)

    { // Works using magic! isItTimeAlready(delay) && callback(); }
  70. // “Deep down in the JavaScript Engine” function setTimeout(callback, delay)

    { // Works using magic! isItTimeAlready(delay) && callback(); }