Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Scope & Closures in JavaScript
Search
Luciano Battagliero
September 20, 2018
Programming
1
270
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
Share
More Decks by Luciano Battagliero
See All by Luciano Battagliero
BEM
battaglr
5
6.1k
Why you should care about whitespace
battaglr
4
290
SMACSS
battaglr
5
500
Other Decks in Programming
See All in Programming
知られざるDMMデータエンジニアの生態 〜かつてツチノコと呼ばれし者〜
takaha4k
1
480
2025.01.17_Sansan × DMM.swift
riofujimon
2
570
CQRS+ES の力を使って効果を感じる / Feel the effects of using the power of CQRS+ES
seike460
PRO
0
240
PHPとAPI Platformで作る本格的なWeb APIアプリケーション(入門編) / phpcon 2024 Intro to API Platform
ttskch
0
390
ecspresso, ecschedule, lambroll を PipeCDプラグインとして動かしてみた (プロトタイプ) / Running ecspresso, ecschedule, and lambroll as PipeCD Plugins (prototype)
tkikuc
2
1.9k
見えないメモリを観測する: PHP 8.4 `pg_result_memory_size()` とSQL結果のメモリ管理
kentaroutakeda
0
940
技術的負債と向き合うカイゼン活動を1年続けて分かった "持続可能" なプロダクト開発
yuichiro_serita
0
300
『改訂新版 良いコード/悪いコードで学ぶ設計入門』活用方法−爆速でスキルアップする!効果的な学習アプローチ / effective-learning-of-good-code
minodriven
28
4.2k
PicoRubyと暮らす、シェアハウスハック
ryosk7
0
230
php-conference-japan-2024
tasuku43
0
430
サーバーゆる勉強会 DBMS の仕組み編
kj455
1
310
月刊 競技プログラミングをお仕事に役立てるには
terryu16
1
1.2k
Featured
See All Featured
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
44
9.4k
Learning to Love Humans: Emotional Interface Design
aarron
274
40k
Adopting Sorbet at Scale
ufuk
74
9.2k
Docker and Python
trallard
43
3.2k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
330
21k
The Art of Programming - Codeland 2020
erikaheidi
53
13k
How GitHub (no longer) Works
holman
312
140k
Code Review Best Practice
trishagee
65
17k
How to train your dragon (web standard)
notwaldorf
89
5.8k
Why Our Code Smells
bkeepers
PRO
335
57k
Optimising Largest Contentful Paint
csswizardry
33
3k
Building Flexible Design Systems
yeseniaperezcruz
328
38k
Transcript
None
None
None
None
None
None
var x = 42; console.log(x);
var x = 42; console.log(x); // → 42
var x = 42; console.log(x); // → 42
var x = 42; console.log(x); // → 42
var x = 42; console.log(x); // → 42
None
None
None
None
None
var y = 40; function foo() { var x =
2; return x + y; } foo();
var y = 40; function foo() { var x =
2; return x + y; } foo(); // → 42
var y = 40; function foo() { var x =
2; return x + y; } foo(); // → 42
var y = 40; function foo() { var x =
2; return x + y; } foo(); // → 42
var y = 40; function foo() { var x =
2; return x + y; } foo(); // → 42
None
var x = 'tree'; function foo() { var x =
'shadow'; return x; } foo();
var x = 'tree'; function foo() { var x =
'shadow'; return x; } foo(); // → shadow
var x = 'tree'; function foo() { var x =
'shadow'; return x; } foo(); // → shadow
var x = 'tree'; function foo() { var x =
'shadow'; return x; } foo(); // → shadow
None
function foo() { var x = 2; return x +
y; } foo();
function foo() { var x = 2; return x +
y; } foo(); // → ReferenceError: y is not defined
function foo() { var x = 2; return x +
y; } foo(); // → ReferenceError: y is not defined
function foo() { var x = 2; return x +
y; } foo(); // → ReferenceError: y is not defined
function foo() { var x = 2; return x +
y; } foo(); // → ReferenceError: y is not defined
None
None
None
None
window
window === this && window === self && window ===
frames
window === this && window === self && window ===
frames // → true
None
global
global === this
global === this // → true
None
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'); };
╯ □ )╯︵ ┻━┻
None
┬─┬ノ ノ
None
var x = 42; console.log(x) console.log(window.x)
var x = 42; console.log(x) // → 42 console.log(window.x) //
→ 42
var x = 42; window.console.log(this.x)
var x = 42; window.console.log(this.x) // → 42
☉ ☉
None
var x = 'tree'; function foo() { var x =
'shadow'; return x; } foo();
var x = 'tree'; function foo() { var x =
'shadow'; return x; } foo(); // → shadow
var x = 'tree'; function foo() { var x =
'shadow'; return window.x; } foo();
var x = 'tree'; function foo() { var x =
'shadow'; return window.x; } foo(); // → tree
None
None
None
None
None
ಥ﹏ಥ
function foo() { var x = 42; console.log(x); }; foo();
console.log(x);
function foo() { var x = 42; console.log(x); // →
42 }; foo(); console.log(x); // → ReferenceError
function foo() { var x = 42; console.log(x); // →
42 }; foo(); console.log(x); // → ReferenceError
function foo() { var x = 42; console.log(x); // →
42 }; foo(); console.log(x); // → ReferenceError
function foo() { var x = 42; console.log(x); // →
42 }; foo(); console.log(x); // → ReferenceError
function foo() { var x = 42; console.log(x); // →
42 }; foo(); console.log(x); // → ReferenceError
None
None
(function () { var x = 42; console.log(x); })(); console.log(x);
(function () { var x = 42; console.log(x); // →
42 })(); console.log(x); // → ReferenceError
(function () { var x = 42; console.log(x); // →
42 })(); console.log(x); // → ReferenceError
(function () { var x = 42; console.log(x); // →
42 })(); console.log(x); // → ReferenceError
(function () { var x = 42; console.log(x); // →
42 })(); console.log(x); // → ReferenceError
(function () { var x = 42; console.log(x); // →
42 })(); console.log(x); // → ReferenceError
None
None
if (true) { var x = 42; console.log(x); } console.log(x);
if (true) { var x = 42; console.log(x); // →
42 } console.log(x); // → 42
if (true) { var x = 42; console.log(x); // →
42 } console.log(x); // → 42
if (true) { var x = 42; console.log(x); // →
42 } console.log(x); // → 42
if (true) { var x = 42; console.log(x); // →
42 } console.log(x); // → 42
if (true) { var x = 42; console.log(x); // →
42 } console.log(x); // → 42
// “Under the hood” var x; if (true) { x
= 42; console.log(x); } console.log(x);
// “Under the hood” var x; if (true) { x
= 42; console.log(x); // → 42 } console.log(x); // → 42
// “Under the hood” var x; if (true) { x
= 42; console.log(x); } console.log(x);
// “Under the hood” var x; if (true) { x
= 42; console.log(x); // → 42 } console.log(x); // → 42
None
None
try { throw 42; } catch(x) { console.log(x); } console.log(x);
try { throw 42; } catch(x) { console.log(x); // →
42 } console.log(x); // → ReferenceError
try { throw 42; } catch(x) { console.log(x); // →
42 } console.log(x); // → ReferenceError
try { throw 42; } catch(x) { console.log(x); // →
42 } console.log(x); // → ReferenceError
try { throw 42; } catch(x) { console.log(x); // →
42 } console.log(x); // → ReferenceError
try { throw 42; } catch(x) { console.log(x); // →
42 } console.log(x); // → ReferenceError
☞ ⌐ ☞
None
None
None
None
None
if (true) { let x = 42; console.log(x); } console.log(x);
if (true) { let x = 42; console.log(x); // →
42 } console.log(x); // → ReferenceError
ノ ∀ ノ⌒・ 。 。 ・゜゚・ ☆
None
{ let x = 42; console.log(x); } console.log(x);
{ let x = 42; console.log(x); // → 42 }
console.log(x); // → ReferenceError
ヽ 〇 ノ
None
None
console.log(x);
console.log(x); // → ReferenceError
┐ 、 ┌
console.log(x); var x;
console.log(x); // → undefined var x;
・・
console.log(x); var x = 42;
console.log(x); // → undefined var x = 42;
ლ ಠ ಠ ლ
None
None
var x = 42;
var x; x = 42;
var x; // Declaration x = 42; // Assignment
None
None
None
None
console.log(x); var x;
console.log(x); // → undefined var x;
// “Under the hood” var x; console.log(x);
// “Under the hood” var x; console.log(x); // → undefined
None
console.log(x); var x = 42;
console.log(x); // → undefined var x = 42;
// “Under the hood” var x; console.log(x); x = 42;
// “Under the hood” var x; console.log(x); // → undefined
x = 42;
None
None
foo(); function foo() { return 42; }
foo(); // → 42 function foo() { return 42; }
o
// “Under the hood” function foo() { return 42; }
foo();
// “Under the hood” function foo() { return 42; }
foo(); // → 42
function foo() { return 2; } foo(); function foo() {
return 4; }
function foo() { return 2; } foo(); // → 4
function foo() { return 4; }
// “Under the hood” function foo() { return 2; }
function foo() { return 4; } foo();
// “Under the hood” function foo() { return 2; }
function foo() { return 4; } foo(); // → 4
function foo() { return 2; } foo(); var foo =
function () { return 4; };
function foo() { return 2; } foo(); // → 2
var foo = function () { return 4; };
งಠ ಠ ง
// “Under the hood” function foo() { return 2; }
var foo; foo(); foo = function () { return 4; };
// “Under the hood” function foo() { return 2; }
var foo; foo(); // → 2 foo = function () { return 4; };
foo(); var foo = function () { return 42; };
foo(); // → TypeError: foo is not a function var
foo = function () { return 42; };
╰ 益 ╯
// “Under the hood” var foo; foo(); foo = function
() { return 42; };
// “Under the hood” var foo; foo(); // → TypeError:
foo is not a function foo = function () { return 42; };
None
None
console.log(x); let x = 42;
console.log(x); // → ReferenceError let x = 42;
ಠ ಠ
None
let x = 2; { console.log(x); let x = 4;
}
let x = 2; { console.log(x); // → ReferenceError let
x = 4; }
None
None
None
None
None
None
None
function foo() { return 'I am a Closure!’; }
☉ ☉
None
None
None
function foo() { let x = 42; return function ()
{ console.log(x); }; } let bar = foo(); bar(); console.log(x);
function foo() { let x = 42; return function ()
{ console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
function foo() { let x = 42; return function ()
{ console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
function foo() { let x = 42; return function ()
{ console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
function foo() { let x = 42; return function ()
{ console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
function foo() { let x = 42; return function ()
{ console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
function foo() { let x = 42; return function ()
{ console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
function foo() { let x = 42; return function ()
{ console.log(x); }; } let bar = foo(); bar(); // → 42 console.log(x); // → ReferenceError
None
None
None
let x = 'FOO_SCOPE'; function foo() { console.log(x); } function
bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo);
let x = 'FOO_SCOPE'; function foo() { console.log(x); } function
bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
let x = 'FOO_SCOPE'; function foo() { console.log(x); } function
bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
let x = 'FOO_SCOPE'; function foo() { console.log(x); } function
bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
let x = 'FOO_SCOPE'; function foo() { console.log(x); } function
bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
let x = 'FOO_SCOPE'; function foo() { console.log(x); } function
bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
let x = 'FOO_SCOPE'; function foo() { console.log(x); } function
bar(callback) { let x = 'BAR_SCOPE'; callback(); } bar(foo); // → FOO_SCOPE
function foo(x) { setTimeout(function () { console.log(x); }, 1000); }
foo(42);
function foo(x) { setTimeout(function () { console.log(x); // → 42
}, 1000); } foo(42);
function foo(x) { setTimeout(function () { console.log(x); // → 42
}, 1000); } foo(42);
function foo(x) { setTimeout(function () { console.log(x); // → 42
}, 1000); } foo(42);
function foo(x) { setTimeout(function () { console.log(x); // → 42
}, 1000); } foo(42);
function foo(x) { setTimeout(function () { console.log(x); // → 42
}, 1000); } foo(42);
// “Deep down in the JavaScript Engine” function setTimeout(callback, delay)
{ // Works using magic! isItTimeAlready(delay) && callback(); }
// “Deep down in the JavaScript Engine” function setTimeout(callback, delay)
{ // Works using magic! isItTimeAlready(delay) && callback(); }
// “Deep down in the JavaScript Engine” function setTimeout(callback, delay)
{ // Works using magic! isItTimeAlready(delay) && callback(); }
ノ ∀ つ──☆ ・゚
function foo(x) { setTimeout(function () { console.log(x); // → 42
}, 1000); } foo(42);
None
None
None
None
None
None
None
None