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
310
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.2k
Why you should care about whitespace
battaglr
4
300
SMACSS
battaglr
5
540
Other Decks in Programming
See All in Programming
AIエージェント開発、DevOps and LLMOps
ymd65536
1
380
Microsoft Orleans, Daprのアクターモデルを使い効率的に開発、デプロイを行うためのSekibanの試行錯誤 / Sekiban: Exploring Efficient Development and Deployment with Microsoft Orleans and Dapr Actor Models
tomohisa
0
230
AIコーディングAgentとの向き合い方
eycjur
0
250
速いWebフレームワークを作る
yusukebe
5
1.6k
私の後悔をAWS DMSで解決した話
hiramax
4
190
AI OCR API on Lambdaを Datadogで可視化してみた
nealle
0
230
開発チーム・開発組織の設計改善スキルの向上
masuda220
PRO
18
9.7k
Claude Codeで実装以外の開発フロー、どこまで自動化できるか?失敗と成功
ndadayo
4
1.9k
実用的なGOCACHEPROG実装をするために / golang.tokyo #40
mazrean
1
180
旅行プランAIエージェント開発の裏側
ippo012
2
810
Processing Gem ベースの、2D レトロゲームエンジンの開発
tokujiros
2
120
go test -json そして testing.T.Attr / Kyoto.go #63
utgwkk
2
230
Featured
See All Featured
How to train your dragon (web standard)
notwaldorf
96
6.2k
The Pragmatic Product Professional
lauravandoore
36
6.8k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
22k
Imperfection Machines: The Place of Print at Facebook
scottboms
268
13k
A better future with KSS
kneath
239
17k
Done Done
chrislema
185
16k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
229
22k
Being A Developer After 40
akosma
90
590k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
580
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
8
910
Visualization
eitanlees
147
16k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
161
15k
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