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
350
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.3k
Why you should care about whitespace
battaglr
4
310
SMACSS
battaglr
5
570
Other Decks in Programming
See All in Programming
AI駆動開発の本音 〜Claude Code並列開発で見えたエンジニアの新しい役割〜
hisuzuya
4
430
CSC307 Lecture 09
javiergs
PRO
1
850
The Ralph Wiggum Loop: First Principles of Autonomous Development
sembayui
0
3.7k
ぼくの開発環境2026
yuzneri
1
290
DSPy入門 Pythonで実現する自動プロンプト最適化 〜人手によるプロンプト調整からの卒業〜
seaturt1e
1
400
朝日新聞のデジタル版を支えるGoバックエンド ー価値ある情報をいち早く確実にお届けするために
junkiishida
1
290
受け入れテスト駆動開発(ATDD)×AI駆動開発 AI時代のATDDの取り組み方を考える
kztakasaki
2
500
DevinとClaude Code、SREの現場で使い倒してみた件
karia
1
790
AIエージェントのキホンから学ぶ「エージェンティックコーディング」実践入門
masahiro_nishimi
7
1.2k
RubyとGoでゼロから作る証券システム: 高信頼性が求められるシステムのコードの外側にある設計と運用のリアル
free_world21
0
130
日本だけで解禁されているアプリ起動の方法
ryunakayama
0
360
go directiveを最新にしすぎないで欲しい話──あるいは、Go 1.26からgo mod initで作られるgo directiveの値が変わる話 / Go 1.26 リリースパーティ
arthur1
2
410
Featured
See All Featured
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
110
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
130
Documentation Writing (for coders)
carmenintech
77
5.3k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
370
Chasing Engaging Ingredients in Design
codingconduct
0
130
What does AI have to do with Human Rights?
axbom
PRO
0
2k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
220
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
400
Navigating the moral maze — ethical principles for Al-driven product design
skipperchong
2
270
The SEO identity crisis: Don't let AI make you average
varn
0
400
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
610
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