Slide 1

Slide 1 text

JavaScript’s variables: scopes, environments, closures Dr. Axel Rauschmayer 2ality.com 2014-03-30 CodeFest 2014

Slide 2

Slide 2 text

A few definitions

Slide 3

Slide 3 text

A few definitions Scope of a variable Where is the variable accessible? function foo() { var x; } foo() is direct scope of x. Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 3 / 32

Slide 4

Slide 4 text

A few definitions Static versus dynamic Adjectives for describing phenomena in programming languages: Static: pertaining to the source code ⇒ The scope of a variable is static function f() { var x = 3; ... // no effect on scope of x } ⇒ Variables in JavaScript are statically scoped (or lexically scoped) Dynamic: at runtime ⇒ function calls are dynamic function g() { } function f() { g() } Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 4 / 32

Slide 5

Slide 5 text

A few definitions var declarations are function-scoped foo is accessible in all of main(): function main() { { // block starts var foo = 4; } // block ends console.log(foo); // 4 } ECMAScript 6: block-scoped variable declarations via let. Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 5 / 32

Slide 6

Slide 6 text

A few definitions Nested scopes Everything from outer scopes is accessible from inner scopes. function foo(arg) { function bar() { console.log('arg: ' + arg); } bar(); } console.log(foo('hello')); // arg: hello Outer scope: foo() Inner scope: bar() arg is accessible in its direct scope foo() and the inner scope bar(). Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 6 / 32

Slide 7

Slide 7 text

Environments

Slide 8

Slide 8 text

Environments Environments: managing variables Environments: Data structure for storing variables Maps from variable names to values Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 8 / 32

Slide 9

Slide 9 text

Environments Dimensions of environments Environments must support: Fresh variables (local, parameters) per function call (dynamic dimension). Nested scopes (static dimension). Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 9 / 32

Slide 10

Slide 10 text

Environments Dynamic dimension: calling functions function fac(n) { if (n <= 1) { return 1; } return n * fac(n - 1); } For each invocation: Allocate storage for parameters and local variables Discard afterwards (usually) Solution: stack of execution contexts (references to environments) Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 10 / 32

Slide 11

Slide 11 text

Environments var foo = 'abc'; function fac(n) { if (n <= 1) { return 1; } return n * fac(n - 1); } // YOU ARE HERE fac(2); 0 … fac 'abc' foo Lexical environments Execution contexts Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 11 / 32

Slide 12

Slide 12 text

Environments var foo = 'abc'; function fac(n) { if (n <= 1) { return 1; } return n * fac(n - 1); } fac(2); 1 0 … fac 'abc' foo 2 n Lexical environments Execution contexts Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 12 / 32

Slide 13

Slide 13 text

Environments var foo = 'abc'; function fac(n) { if (n <= 1) { return 1; } return n * fac(n - 1); } fac(2); 2 1 0 … fac 'abc' foo 1 n Lexical environments Execution contexts 2 n Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 13 / 32

Slide 14

Slide 14 text

Environments Static (lexical) dimension: nested scopes function f(x) { var foo; function g(y, z) { var bar; } } Environment: field outer points to “surrounding” environment. Search environment chain for variables. Function: property [[Scope]] points to environment “in which” function was created. Function call: set up outer via [[Scope]]. Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 14 / 32

Slide 15

Slide 15 text

Environments function f(x) { var foo; function g(y, z) { var bar; } g(7, 1); } // YOU ARE HERE f(2); 0 … f Lexical environments Execution contexts Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 15 / 32

Slide 16

Slide 16 text

Environments function f(x) { var foo; function g(y, z) { var bar; } g(7, 1); } f(2); 1 0 … f … g undefined foo 2 x outer Lexical environments Execution contexts Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 16 / 32

Slide 17

Slide 17 text

Environments function f(x) { var foo; function g(y, z) { var bar; } g(7, 1); } f(2); 2 1 0 … f … g undefined foo 2 x outer Lexical environments Execution contexts undefined bar 1 z 7 y outer Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 17 / 32

Slide 18

Slide 18 text

Closures

Slide 19

Slide 19 text

Closures Closures: Functions Stay Connected to Their Birth Scopes function createInc(startValue) { return function (step) { startValue += step; return startValue; }; } # var inc = createInc(5); # inc(1) 6 # inc(2) 8 Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 19 / 32

Slide 20

Slide 20 text

Closures What is a closure? Closure = function + connection to birth scope Via internal property [[Scope]] of functions Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 20 / 32

Slide 21

Slide 21 text

Closures Example: closures Step 1 function createInc(startValue) { return function (step) { startValue += step; return startValue; }; } var inc = createInc(5); 0 undefined inc createInc Lexical environments Execution contexts Functions [[Scope]] Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 21 / 32

Slide 22

Slide 22 text

Closures Step 2 function createInc(startValue) { return function (step) { startValue += step; return startValue; }; } var inc = createInc(5); 1 0 undefined inc createInc 5 startValue outer Lexical environments Execution contexts Functions [[Scope]] Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 22 / 32

Slide 23

Slide 23 text

Closures Step 3 function createInc(startValue) { return function (step) { startValue += step; return startValue; }; } var inc = createInc(5); 0 inc createInc 5 startValue outer [[Scope]] Lexical environments Execution contexts Functions [[Scope]] Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 23 / 32

Slide 24

Slide 24 text

Closures Step 4 function createInc(startValue) { return function (step) { startValue += step; return startValue; }; } var inc = createInc(5); console.log(inc(1)); // 6 1 0 inc createInc 5 startValue 1 step outer outer [[Scope]] Lexical environments Execution contexts Functions [[Scope]] Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 24 / 32

Slide 25

Slide 25 text

Closures Step 5 function createInc(startValue) { return function (step) { startValue += step; return startValue; }; } var inc = createInc(5); console.log(inc(1)); // 6 0 inc createInc 5 startValue outer [[Scope]] Lexical environments Execution contexts Functions [[Scope]] Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 25 / 32

Slide 26

Slide 26 text

Thank you! Free online: speakingjs.com

Slide 27

Slide 27 text

Bonus: inadvertent sharing

Slide 28

Slide 28 text

Bonus: inadvertent sharing Wrong: all functions share the same i function f() { var result = []; for (var i=0; i<3; i++) { var func = function () { return i; }; result.push(func); } return result; } console.log(f()[1]()); // 3 Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 28 / 32

Slide 29

Slide 29 text

Bonus: inadvertent sharing Right: one environment per function, with snapshot of i function f() { var result = []; for (var i=0; i<3; i++) { (function () { // step 1: IIFE var pos = i; // step 2: copy var func = function () { return pos; }; result.push(func); }()); } return result; } console.log(f()[1]()); // 1 Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 29 / 32

Slide 30

Slide 30 text

Bonus: example

Slide 31

Slide 31 text

Bonus: example Example: environments Step 1 function myFunction(myParam) { var myVar = 123; return myFloat; } var myFloat = 1.3; // Step 1 myFunction('abc'); // Step 2 0 1.3 myFloat myFunction Chain of environments (lexical) Stack of execution contexts (dynamic) [[Scope]] function (myParam) ... } Functions Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 31 / 32

Slide 32

Slide 32 text

Bonus: example Step 2 function myFunction(myParam) { var myVar = 123; return myFloat; } var myFloat = 1.3; // Step 1 myFunction('abc'); // Step 2 [[Scope]] 1 0 1.3 myFloat myFunction myVar 123 'abc' myParam outer function (myParam) ... } Chain of environments (lexical) Stack of execution contexts (dynamic) Functions Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 32 / 32