![Page 1: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/1.jpg)
softwarestudio functions, scope & closures
Daniel Jackson 1
![Page 2: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/2.jpg)
functions as values
2
![Page 3: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/3.jpg)
making functions
function expression › function (args) {body}
functions are ‘polymorphic’ › implicit typed › depends on how args used
> three = function () {return 3;} function () {return 3;} > three function () {return 3;} > three() 3 > id = function (x) {return x;} function (x) {return x;} > id(3) 3 > id(true) true > id(id) function (x) {return x;} > (id(id))(3) 3
3
![Page 4: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/4.jpg)
functions are first class > seq = function () {
seq.c += 1; return seq.c;}just like other objects function () {seq.c += 1; return
seq.c;}› can bind to variables > seq.c = 0
› can put in property slots 0 note: bad lack of › can add property slots > seq()
1 encapsulation! will fix > seq() later with closures 2
> seq = function () {return (seq.c = seq.next(seq.c));} function () {return (seq.c = seq.next(seq.c));} > seq.c = 0 0 > seq.next = function (i) {return i + 2;} function (i) {return i + 2;} > seq() 2 > seq() 4 4
![Page 5: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/5.jpg)
recursion
can you explain › how a recursive definition works? › when exactly is the function defined?
> fact = function (i) {if (i===0) return 1; else return i * fact(i-1);} function (i) {if (i===0) return 1; else return i * fact(i-1);} > fact (4) 24
5
![Page 6: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/6.jpg)
a puzzle: repeated applications
suppose you see an expression e › eg, e is f() › what might expression do?
evaluation can have 3 effects › value is returned (or exception thrown) › objects are modified › environment is updated
a puzzle › declare f so that f()===f() evals to false
6
![Page 7: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/7.jpg)
evaluating functions
7
![Page 8: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/8.jpg)
two phases > (function (x) {return x + 1;}) (3) 4
creation › function expression evaluated
application › function body evaluated
evaluation order for applications › first evaluate arguments, left to right › then evaluate body
> log = function (s) {console.log(s + seq());} function (s) {console.log(s + seq());} > (function () {log('c')}) (log('a'),log('b')) a1 b2 c3
8
![Page 9: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/9.jpg)
evaluating the body
what environment is body evaluated in? › same environment application is evaluated in?
let’s see! › hmm...
> x = 1 1 > f = (function (x) {return function () {return x;};}) (x) function () {return x;} > f() 1 > x = 2 2 > f() 1
9
![Page 10: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/10.jpg)
two environments
when function is created › keeps environment as a property › called ‘function scope’ › uses this environment to evaluate body in
what about arguments? › new environment (‘frame’) with bindings for args › linked to function scope
10
![Page 11: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/11.jpg)
body of function is an object model evaluated in context of function’s scope
_proto
› activation distinction from (syntactic) statement › underscores emphasize: not real properties
Function
Activation Environment
_scope
context !
?
_body
!
?Statement
stmt !
?
creates
? scope of a function
is context it was created in
11
![Page 12: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/12.jpg)
aah, nostalgia!
Courtesy of Harold Abelson and Gerald Jay Sussman. Used with permission.
From Structure and Interpretation of Computer Programs.
12
![Page 13: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/13.jpg)
examples
13
![Page 14: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/14.jpg)
> f = function () {return x;}function () {return x;}> x = 11> f()
> x = 2
> f()
example 1 > f = function () {return x;} function () {return x;} > x = 1 1 > f() 1 > x = 2 2 > f() 2
what happens here? › function scope is top-level environment › assignment to x modifies binding in top-level environment › so in this case x refers to x of application environment too
14
![Page 15: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/15.jpg)
simulating example 1
3.1 return x; (Activation)
return x; (Statement)
stmt
body
1. f = function () {return x;} (Activation)
stmtf = function () {return x;} (Statement)
context (Env)
(Function)
creates
2. x = 1 (Activation)
bindings (Binding)
x (Var)
1 (Object)
var
value
3. f() (Activation)
4. x = 2 (Activation)
2 (Object)
5. f() (Activation)
5.1 return x; (Activation)
stmt
> f = function () {return x;} function () {return x;} > x = 1 1 > f() 1 > x = 2 2 > f() 2
_scope
15
![Page 16: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/16.jpg)
> f = function (x) {return x;}function (x) {return x;}> x = 11> y = 22> f(y)
example 2
> f = function (x) {return x;} function (x) {return x;} > x = 1 1 > y = 2 2 > f(y) 2
what happens here? › function scope is top-level environment › when application is evaluated, argument x is bound to 2 › local x said to shadow global x
16
![Page 17: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/17.jpg)
simulating example 2
4.1 return x; (Activation)
return x; (Statement)
stmt
body
1. f = function (x) {return x;} (Activation)
contextstmtf = function (x) {return x;} (Statement)
(Env)
(Function)
creates _scope
bindings
2. x = 1 (Activation)
(Binding)
x (Var)
1 (Object)
var
value
3. y = 2 (Activation)
(Binding)
y (Var)
2 (Object)
var
value
bindings
4. f(y) (Activation)
_proto
(Binding)
x (Var)
2 (Object)
var
value
(Env)
> f = function (x) {return x;} function (x) {return x;} > x = 1 1 > y = 2 2 > f(y) 2
17
![Page 18: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/18.jpg)
> x = 11> f = (function (x) {return function () {return x;};}) (x)function () {return x;}> f()
> x = 22> f()
example 3 > x = 1 1 > f = (function (x) {return function () {return x;};}) (x) function () {return x;} > f() 1 > x = 2 2 > f() 1
what happens here? › when f is applied, x is bound to 1 in new frame › anonymous function has scope with x bound to 1 › assignment to top-level x does not modify this scope
18
![Page 19: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/19.jpg)
body
4.1 return x (Activation)
3. x = 2 (Activation)
simulating example 3
> x = 1 1 > f = (function (x) {
return function () {return x;};}) (x)
function () {return x;} > x = 2 2 > f() 1
context1. x = 1 (Activation)
(Env) bindings
(Binding)
x (Var)
1 (Object)
var
value
2. f = ... (Activation)
stmt f = (function (x) { return function () {return x;}}) (x)
(Statement)
(Function)
_scope
_proto
(Binding)
x (Var)
1 (Object)
var
value
(Env) bindings
2.1 return function ... (Activation)
(Function)
creates
_scope
2 (Object)
4. f() (Activation)
19
![Page 20: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/20.jpg)
> f = (function (x) {return function () {x += 1; return x;};}) (0)function () {x += 1; return x;}> f()
> f()
example 4
> f = (function (x) {return function () {x += 1; return x;};}) (0) function () {x += 1; return x;} > f() 1 > f() 2
what if we modify x? › when f is applied, x is bound to 0 in new frame › anonymous function has scope with x bound to 0 › this ‘internal’ x is updated every time f is called
20
![Page 21: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/21.jpg)
simulating example 4
_proto
> f = (function (x) { return function () {x += 1; return x;};}) (0)
function (){x += 1; return x;} > f()
1. f = ... (Activation)
contextstmt f = (function (x) { return function ()
{x += 1; return x;};}) (0) (Statement)
(Env)
(Function)
creates _scope
(Binding)
x (Var)
0 (Object)
var
(Env)creates
value
bindings
2.1 return function ... (Activation)
(Function)
_scope
body3. f() (Activation)
3.1 x += 1 (Activation)
1 (Object)
1 21
![Page 22: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/22.jpg)
local variables
22
![Page 23: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/23.jpg)
> sum = function (a) { s = 0; for (i = 0; i < a.length; i += 1) s += a[i]; return s;}function...> sum([1,2,3])6
> sum = function (a) { s = 0; for (i = 0; i < a.length; i += 1) s += a[i]; return s;}function...> sum([1,2,3])6> s6> i3
what’s wrong with this function?how to fix it?
avoiding pollution > sum = function (a, s, i) {
s = 0; for (i = 0; i < a.length; i += 1) s += a[i]; return s;}
function... > sum([1,2,3]) 6 > s ReferenceError why does this work? > i ReferenceError
23
![Page 24: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/24.jpg)
argument mismatch
when arguments are › missing: initialized to undefined › extra: ignored
> inc = function (x, y) {return y ? x+y : x+1;} function (x, y) {return y ? x+y : x+1;} > inc(1) 2 > inc(1,2) 3 > inc(1,2,3) 3
24
![Page 25: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/25.jpg)
var decls > sum = function (a, s, i) {
s = 0; for (i = 0; i < a.length; i += 1) s += a[i]; return s;}
function...
don’t want bogus arguments › so Javascript has a special statement › “var x” creates a binding for x in the immediate env
> sum = function (a) { var s = 0;
for (var i = 0; i < a.length; i += 1) s += a[i]; return s;}
function...
note: doesn’t matter where var decl occurs in function even in dead code!
25
![Page 26: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/26.jpg)
function declarations
function declaration syntax › function f () {} short for var f = function () {} › but not quite, so don’t use it!
var f = function(){ if (true) {
function g() { return 1;}; › ECMA: 2 } else { function g() { return 2;}; › Safari, Chrome: 3
} › Mozilla: 4 var g = function() { return 3;} return g(); function g(){ return 4;}
} var result = f();
26
![Page 27: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/27.jpg)
lexical vs dynamic scoping
27
![Page 28: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/28.jpg)
a language design question
x = 1; g = function(){ console.log(x); x=2; } f = function(){ var x = 3; g(); } f(); console.log(x);
what does this print? › lexical scoping: 1, 2 › dynamic scoping: 3, 1
lexical scoping now preferred › harder to implement › better for programmer
28
![Page 29: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/29.jpg)
a common misunderstanding
29
![Page 30: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/30.jpg)
lookup at activation time
var multipliers = function makeMultipliers (max) { var result = []; for (var i = 0; i < max; i++)
result.push (function (x) {return x * i;}); return result;
}
> multipliers(10) [2] (5) ???
what’s the value? › 50, not 5
can you fix it?
30
![Page 31: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/31.jpg)
summary
functions are first-class › values created by expressions › bound to variables › stored as properties, and can have properties
lexical closures › free variables bound in ‘declaration’ environment
local vars › added to local environment, just like function args
next › exploiting functions & closures in programming
31
![Page 32: JavaScript: Functions, Scope & Closures · PDF filemaking functions. function expression › function (args) {body} functions are ‘polymorphic’ › implicit typed › depends on](https://reader030.vdocuments.us/reader030/viewer/2022020302/5a843a537f8b9a882e8b5af9/html5/thumbnails/32.jpg)
MIT OpenCourseWarehttp://ocw.mit.edu
6.170 Software StudioSpring 2013
For information about citing these materials or our Terms of Use, visit: http://ocw.mit.edu/terms.