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

CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

  • View
    523

  • Download
    2

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

JavaScript’s variables: scopes, environments, closures

Dr. Axel Rauschmayer

2ality.com

2014-03-30

CodeFest 2014

Page 2: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

A few definitions

Page 3: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

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

Page 4: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

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

Page 5: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

A few definitions

var declarations are function-scoped

foo is accessible in all of main():

function main() {{ // block starts

var foo = 4;} // block endsconsole.log(foo); // 4

}

ECMAScript 6: block-scoped variable declarations via let.

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 5 / 32

Page 6: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

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

Page 7: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Environments

Page 8: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

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

Page 9: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

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

Page 10: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

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 variablesDiscard afterwards (usually)

Solution: stack of execution contexts (references to environments)

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 10 / 32

Page 11: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Environments

var foo = 'abc';function fac(n) {

if (n <= 1) {return 1;

}return n * fac(n - 1);

}// YOU ARE HEREfac(2);

0…fac

'abc'foo

Lexical environmentsExecution contexts

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 11 / 32

Page 12: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Environments

var foo = 'abc';function fac(n) {

if (n <= 1) {return 1;

}return n * fac(n - 1);

}fac(2);

10

…fac'abc'foo

2n

Lexical environmentsExecution contexts

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 12 / 32

Page 13: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Environments

var foo = 'abc';function fac(n) {

if (n <= 1) {return 1;

}return n * fac(n - 1);

}fac(2);

210

…fac'abc'foo

1n

Lexical environmentsExecution contexts

2n

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 13 / 32

Page 14: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

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 forvariables.

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

Page 15: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Environments

function f(x) {var foo;function g(y, z) {

var bar;}g(7, 1);

}// YOU ARE HEREf(2);

0 …f

Lexical environmentsExecution contexts

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 15 / 32

Page 16: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Environments

function f(x) {var foo;function g(y, z) {

var bar;}g(7, 1);

}f(2);

10 …f

…gundefinedfoo

2x

outer

Lexical environmentsExecution contexts

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 16 / 32

Page 17: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Environments

function f(x) {var foo;function g(y, z) {

var bar;}g(7, 1);

}f(2);

210 …f

…gundefinedfoo

2x

outer

Lexical environmentsExecution contexts

undefinedbar1z7y

outer

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 17 / 32

Page 18: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Closures

Page 19: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

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

Page 20: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

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

Page 21: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Closures

Example: closuresStep 1

function createInc(startValue) {return function (step) {

startValue += step;return startValue;

};}var inc = createInc(5);

0undefinedinc

createInc

Lexical environmentsExecution contexts Functions

[[Scope]]

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 21 / 32

Page 22: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Closures

Step 2

function createInc(startValue) {return function (step) {

startValue += step;return startValue;

};}var inc = createInc(5);

10

undefinedinccreateInc

5startValueouter

Lexical environmentsExecution contexts Functions

[[Scope]]

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 22 / 32

Page 23: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Closures

Step 3

function createInc(startValue) {return function (step) {

startValue += step;return startValue;

};}var inc = createInc(5);

0inccreateInc

5startValueouter

[[Scope]]

Lexical environmentsExecution contexts Functions

[[Scope]]

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 23 / 32

Page 24: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Closures

Step 4function createInc(startValue) {

return function (step) {startValue += step;return startValue; }; }

var inc = createInc(5);console.log(inc(1)); // 6

10

inccreateInc

5startValue

1step

outer

outer

[[Scope]]

Lexical environmentsExecution contexts Functions

[[Scope]]

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 24 / 32

Page 25: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Closures

Step 5

function createInc(startValue) {return function (step) {

startValue += step;return startValue;

};}var inc = createInc(5);console.log(inc(1)); // 6

0inccreateInc

5startValueouter

[[Scope]]

Lexical environmentsExecution contexts Functions

[[Scope]]

Dr. Axel Rauschmayer (2ality.com) JavaScript’s variables 2014-03-30 25 / 32

Page 26: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Thank you!

Free online: speakingjs.com

Page 27: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Bonus: inadvertent sharing

Page 28: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

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

Page 29: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

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: IIFEvar pos = i; // step 2: copyvar 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

Page 30: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Bonus: example

Page 31: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Bonus: example

Example: environments

Step 1function myFunction(myParam) {

var myVar = 123;return myFloat;

}var myFloat = 1.3;// Step 1myFunction('abc'); // Step 2

01.3myFloat

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

Page 32: CodeFest 2014. Axel Rauschmayer — JavaScript’s variables: scopes, environments, closures

Bonus: example

Step 2function myFunction(myParam) {

var myVar = 123;return myFloat;

}var myFloat = 1.3;// Step 1myFunction('abc'); // Step 2

[[Scope]]10

1.3myFloatmyFunction

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