function foo() {const secret = Math.trunc(Math.random() * 100)return function inner() {console.log(`The secret number is ${secret}.`)}}const f = foo() // `secret` is not directly accessible from outside `foo`f() // The only way to retrieve `secret`, is to invoke `f`
In the following example, all the implementation details are hidden inside an immediately executed function expression. The functions tick and toString close over the private state and functions they need to complete their work. Closures have enabled us to modularize and encapsulate our code.
let namespace = {};
(function foo(n) {let numbers = []
function format(n) {return Math.trunc(n)}
function tick() {numbers.push(Math.random() * 100)}
function toString() {return numbers.map(format)}
n.counter = {tick,toString}}(namespace))
const counter = namespace.countercounter.tick()counter.tick()console.log(counter.toString())
function foo() {var result = []for (var i = 0; i < 3; i++) {result.push(function inner() { console.log(i) } )}
return result}
const result = foo()// The following will print `3`, three times...for (var i = 0; i < 3; i++) {result[i]()}
function i() {var x = 'mochacchino'return function j() {console.log('Printing the value of x, from within function j: ', x)}}
const k = i()setTimeout(k, 500) // invoke k (which is j) after 500ms
在闭包中,外部词法环境自己中的变量可用,没有副本。
function l() {var y = 'vanilla';
return {setY: function(value) {y = value;},logY: function(value) {console.log('The value of y is: ', y);}}}
const o = l()o.logY() // The value of y is: vanillao.setY('chocolate')o.logY() // The value of y is: chocolate
/** When a function is defined in another function and it* has access to the outer function's context even after* the outer function returns.** An important concept to learn in JavaScript.*/
function outerFunction(someNum) {var someString = 'Hey!';var content = document.getElementById('content');function innerFunction() {content.innerHTML = someNum + ': ' + someString;content = null; // Internet Explorer memory leak for DOM reference}innerFunction();}
outerFunction(1);
var isVotedUp = false;var isVotedDown = false;
function voteUp_click() {if (isVotedUp)return;else if (isVotedDown)SetDownVote(false);elseSetUpVote(true);}
function voteDown_click() {if (isVotedDown)return;else if (isVotedUp)SetUpVote(false);elseSetDownVote(true);}
function SetUpVote(status) {isVotedUp = status;// Do some CSS stuff to Vote-Up button}
function SetDownVote(status) {isVotedDown = status;// Do some CSS stuff to Vote-Down button}
function sleepOver(howManyControllersToBring) {
var numberOfDansControllers = howManyControllersToBring;
return function danInvitedPaul(numberOfPaulsControllers) {var totalControllers = numberOfDansControllers + numberOfPaulsControllers;return totalControllers;}}
var howManyControllersToBring = 1;
var inviteDan = sleepOver(howManyControllersToBring);
// The only reason Paul was invited is because Dan was invited.// So we set Paul's invitation = Dan's invitation.
var danInvitedPaul = inviteDan(howManyControllersToBring);
alert("There were " + danInvitedPaul + " controllers brought to the party.");
var create = function (x) {var f = function () {return x; // We can refer to x here!};return f;};// 'create' takes one argument, creates a function
var g = create(42);// g is a function that takes no arguments now
var y = g();// y is 42 here
var db = (function() {// Create a hidden object, which will hold the data// it's inaccessible from the outside.var data = {};
// Make a function, which will provide some access to the data.return function(key, val) {if (val === undefined) { return data[key] } // Getelse { return data[key] = val } // Set}// We are calling the anonymous surrounding function,// returning the above inner function, which is a closure.})();
db('x') // -> undefineddb('x', 1) // Set x to 1db('x') // -> 1// It's impossible to access the data object itself.// We are able to get or set individual it.
function makeKitchen() {var trashBags = ['A', 'B', 'C']; // only 3 at first
return {getTrashBag: function() {return trashBags.pop();}};}
var kitchen = makeKitchen();
console.log(kitchen.getTrashBag()); // returns trash bag Cconsole.log(kitchen.getTrashBag()); // returns trash bag Bconsole.log(kitchen.getTrashBag()); // returns trash bag A
function foo (initValue) {//This variable is not destroyed when the foo function exits.//It is 'captured' by the two nested functions returned below.var value = initValue;
//Note that the two returned functions are created right now.//If the foo function is called again, it will return//new functions referencing a different 'value' variable.return {getValue: function () { return value; },setValue: function (newValue) { value = newValue; }}}
function bar () {//foo sets its local variable 'value' to 5 and returns an object with//two functions still referencing that local variablevar obj = foo(5);
//Extracting functions just to show that no 'this' is involved herevar getValue = obj.getValue;var setValue = obj.setValue;
alert(getValue()); //Displays 5setValue(10);alert(getValue()); //Displays 10
//At this point getValue and setValue functions are destroyed//(in reality they are destroyed at the next iteration of the garbage collector).//The local variable 'value' in the foo is no longer referenced by//anything and is destroyed too.}
bar();
// A function that generates a new function for adding numbers.function addGenerator( num ) {// Return a simple function for adding two numbers// with the first number borrowed from the generatorreturn function( toAdd ) {return num + toAdd};}
// addFive now contains a function that takes one argument,// adds five to it, and returns the resulting number.var addFive = addGenerator( 5 );// We can see here that the result of the addFive function is 9,// when passed an argument of 4.alert( addFive( 4 ) == 9 );
// Declare counter outside event handler's scopevar counter = 0;var element = document.getElementById('button');
element.addEventListener("click", function() {// Increment outside countercounter++;
if (counter === 3) {// Do something every third timeconsole.log("Third time's the charm!");
// Reset countercounter = 0;}});
<button id="button">Click Me!</button>
Now this will work, but it does encroach into the outer scope by adding a variable, whose sole purpose is to keep track of the count. In some situations, this would be preferable as your outer application might need access to this information. But in this case, we are only changing every third click's behavior, so it is preferable to enclose this functionality inside the event handler.
Consider this option
var element = document.getElementById('button');
element.addEventListener("click", (function() {// init the count to 0var count = 0;
return function(e) { // <- This function becomes the click handlercount++; // and will retain access to the above `count`
if (count === 3) {// Do something every third timeconsole.log("Third time's the charm!");
//Reset countercount = 0;}};})());
<button id="button">Click Me!</button>
Notice a few things here.
In the above example, I am using the closure behavior of JavaScript. This behavior allows any function to have access to the scope in which it was created, indefinitely. To practically apply this, I immediately invoke a function that returns another function, and because the function I'm returning has access to the internal count variable (because of the closure behavior explained above) this results in a private scope for usage by the resulting function... Not so simple? Let's dilute it down...
A simple one-line closure
// _______________________Immediately invoked______________________// | |// | Scope retained for use ___Returned as the____ |// | only by returned function | value of func | |// | | | | | |// v v v v v vvar func = (function() { var a = 'val'; return function() { alert(a); }; })();
function playingInBrothersRoom (withToys) {// We closure toys which we played in the brother's room. When he come back and lock the door// your brother is supposed to be into the outer [[scope]] object now. Thanks god you could communicate with him.var closureToys = withToys || [],returnToy, countIt, toy; // Just another closure helpers, for brother's inner use.
var brotherGivesToyBack = function (toy) {// New request. There is not yet closureToys on brother's hand yet. Give him a time.returnToy = null;if (toy && closureToys.length > 0) { // If we ask for a specific toy, the brother is going to search for it.
for ( countIt = closureToys.length; countIt; countIt--) {if (closureToys[countIt - 1] == toy) {returnToy = 'Take your ' + closureToys.splice(countIt - 1, 1) + ', little boy!';break;}}returnToy = returnToy || 'Hey, I could not find any ' + toy + ' here. Look for it in another room.';}else if (closureToys.length > 0) { // Otherwise, just give back everything he has in the room.returnToy = 'Behold! ' + closureToys.join(', ') + '.';closureToys = [];}else {returnToy = 'Hey, lil shrimp, I gave you everything!';}console.log(returnToy);}return brotherGivesToyBack;}// You are playing in the house, including the brother's room.var toys = ['teddybear', 'car', 'jumpingrope'],askBrotherForClosuredToy = playingInBrothersRoom(toys);
// The door is locked, and the brother came from the school. You could not cheat and take it out directly.console.log(askBrotherForClosuredToy.closureToys); // Undefined
// But you could ask your brother politely, to give it back.askBrotherForClosuredToy('teddybear'); // Hooray, here it is, teddybearaskBrotherForClosuredToy('ball'); // The brother would not be able to find it.askBrotherForClosuredToy(); // The brother gives you all the restaskBrotherForClosuredToy(); // Nothing left in there
function the_closure() {var x = 4;return function () {return x; // Here, we look back inside the_closure for the value of x}}
var myFn = the_closure();myFn(); //=> 4
function Baby(){this.iTrustYou = true;}
Baby.prototype.hug = function (baby) {var smiles = 0;
if (baby.iTrustYou) {return function() {smiles++;alert(smiles);};}};
vararman = new Baby("Arman"),morgan = new Baby("Morgana");
var hug = arman.hug(morgan);hug();hug();
var plane = function(defaultAirport) {
var lastAirportLeft = defaultAirport;
var car = {driver: {startAccessPlaneInfo: function() {setInterval(function() {console.log("Last airport was " + lastAirportLeft);}, 2000);}}};car.driver.startAccessPlaneInfo();
return {leaveTheAirport: function(airPortName) {lastAirportLeft = airPortName;}}}("Boryspil International Airport");
plane.leaveTheAirport("John F. Kennedy");
console.log('CLOSURES DONE RIGHT');
var arr = [];
function createClosure(n) {return function () {return 'n = ' + n;}}
for (var index = 0; index < 10; index++) {arr[index] = createClosure(index);}
for (var index of arr) {console.log(arr[index]());}
console.log('CLOSURES DONE WRONG');
function createClosureArray() {var badArr = [];
for (var index = 0; index < 10; index++) {badArr[index] = function () {return 'n = ' + index;};}return badArr;}
var badArr = createClosureArray();
for (var index of badArr) {console.log(badArr[index]());}
function person(name, age){
var name = name;var age = age;
function introduce(){alert("My name is "+name+", and I'm "+age);}
return introduce;}
var a = person("Jack",12);var b = person("Matt",14);
a(); //My name is Jack, and I'm 12b(); //My name is Matt, and I'm 14
抽象闭包可以表示为这样的东西:
closure a = {name: "Jack",age: 12,call: function introduce(){alert("My name is "+name+", and I'm "+age);}}
closure b = {name: "Matt",age: 14,call: function introduce(){alert("My name is "+name+", and I'm "+age);}}
init: pass first what's needed...action: in order to achieve something for later execution.
对于一个6岁的孩子,我会强调闭包的实际方面:
Daddy: Listen. Could you bring mum some milk (2).Tom: No problem.Daddy: Take a look at the map that Daddy has just made: mum is there and daddy is here.Daddy: But get ready first. And bring the map with you (1), it may come in handyDaddy: Then off you go (3). Ok?Tom: A piece of cake!
示例:带些牛奶给妈妈(=动作)。首先准备好并带上地图(=init)。
function getReady(map) {var cleverBoy = 'I examine the ' + map;return function(what, who) {return 'I bring ' + what + ' to ' + who + 'because + ' cleverBoy; //I can access the map}}var offYouGo = getReady('daddy-map');offYouGo('milk', 'mum');
function makeAdder(x) {return function(y) {return x + y;};}
var add5 = makeAdder(5);var add10 = makeAdder(10);
console.log(add5(2)); // 7console.log(add10(2)); // 12
示例2:这里通过返回对象文字来实现闭包。
function makeAdder(x) {return {add: function(y){return x + y;}}}
var add5 = makeAdder(5);console.log(add5.add(2));//7
var add10 = makeAdder(10);console.log(add10.add(2));//12
示例3:jQuery中的闭包
$(function(){var name="Closure is easy";$('div').click(function(){$('p').text(name);});});
function sayHello(name) {var text = 'Hello ' + name; // Local variableconsole.log(text);var sayAlert = function () {alert(text);}return sayAlert;}
sayHello();/* This will write 'Hello undefined' to the console (in Chrome anyway),but will not alert though since it returns a function handle to nothing).Since no handle or reference is created, I imagine a good js engine woulddestroy/dispose of the internal sayAlert function once it completes. */
// Create a handle/reference/instance of sayHello() using the name 'Bob'sayHelloBob = sayHello('Bob');sayHelloBob();
// Create another handle or reference to sayHello with a different namesayHelloGerry = sayHello('Gerry');sayHelloGerry();
/* Now calling them again demonstrates that each handle or reference contains its ownunique local variable memory space. They remain in memory 'forever'(or until your computer/browser explode) */sayHelloBob();sayHelloGerry();
var outer = function(params){ //Outer function defines a variable called paramsvar inner = function(){ // Inner function has access to the params variable of the outer functionreturn params;}return inner; //Return inner function exposing it to outer scope},myFunc = outer("myParams");myFunc(); //Returns "myParams"
// 'name' is resolved in the namespace created for one invocation of bindMessage// the processor cannot enter this namespace by the time displayMessage is calledfunction bindMessage(name, div) {
function displayMessage() {alert('This is ' + name);}
$(div).click(displayMessage);}
function sing(person) {
var firstPart = "There was " + person + " who swallowed ";
var fly = function() {var creature = "a fly";var result = "Perhaps she'll die";alert(firstPart + creature + "\n" + result);};
var spider = function() {var creature = "a spider";var result = "that wiggled and jiggled and tickled inside her";alert(firstPart + creature + "\n" + result);};
var bird = function() {var creature = "a bird";var result = "How absurd!";alert(firstPart + creature + "\n" + result);};
var cat = function() {var creature = "a cat";var result = "Imagine That!";alert(firstPart + creature + "\n" + result);};
fly();spider();bird();cat();}
var person="an old lady";
sing(person);
GLOBAL VARIABLE:人是一个全局变量,这意味着如果您将其值从“a old Lady”更改为“a Young man”,则人将一直是一个年轻人,直到您决定再次更改它并且代码中的任何其他函数都可以看到它是一个年轻人。按F12按钮或查看选项设置以打开浏览器的开发人员控制台并键入“man”以查看该值是多少。键入person="a young man"以更改它,然后再次键入“man”以查看它已更改。
var calculate = {number: 0,init: function (num) {this.number = num;},add: function (val) {this.number += val;},rem: function (val) {this.number -= val;}};
并从calculate.number变量中读取结果,无论如何都需要“返回”。
//AdditionFirst think about scope which defines what variable you have to access to (In Javascript);
//there are two kinds of scopeGlobal Scope which include variable declared outside function or curly brace
let globalVariable = "foo";
要记住的一件事是,一旦你声明了一个全局变量,你就可以在代码中的任何地方使用它,甚至在函数中;
本地范围,其中包括仅在代码的特定部分中可用的变量:
函数作用域是当您在函数中声明变量时,您只能在函数中访问该变量
function User(){let name = "foo";alert(name);}alert(name);//error
//Block scope is when you declare a variable within a block then you can access that variable only within a block{let user = "foo";alert(user);}alert(user);//Uncaught ReferenceError: user is not defined at.....
//A Closure
function User(fname){return function(lname){return fname + " " lname;}}let names = User("foo");alert(names("bar"));
//When you create a function within a function you've created a closure, in our example above since the outer function is returned the inner function got access to outer function's scope
var Closure = (function () {// This is a closure// Any methods, variables and properties you define here are "private"// and can't be accessed from outside the function.
//This is a private variablevar foo = "";
//This is a private methodvar method = function(){
}})();
另一方面,如果你想让一个或多个变量或方法在闭包之外可见,你可以在对象文字中返回它们。像这样:
var Closure = (function () {// This is a closure// Any methods, variables and properties you define here are "private"// and can't be accessed from outside the function.
//This is a private variablevar foo = "";
//This is a private methodvar method = function(){
}
//The method will be accessible from outside the closurereturn {method: method}
})();
Closure.method();
var parent = function() {var name = "Mary";var child = function(childName) {// I can also see that "name" is "Mary"}}
因此,只要我们在父函数中,它就可以创建一个或多个子函数,这些子函数确实从秘密位置共享秘密变量。
但可悲的是,如果子函数也是其父函数的私有变量,那么当父函数结束时,它也会死亡,秘密也会随之死亡。
为了活下去,孩子必须在为时已晚之前离开
var parent = function() {var name = "Mary";var child = function(childName) {return "My name is " + childName +", child of " + name;}return child; // child leaves the parent ->}var child = parent(); // < - and here it is outside
var x = 1;function myFN() {alert(x); //1, as opposed to undefined.}// Orfunction a() {var x = 1;function b() {alert(x); //1, as opposed to undefined.}b();}
function foo() {var a = 2;
function bar() {console.log( a );}return bar;}
function test() {var bz = foo();bz();}
// prints 2. Here function bar referred by var bz is outside// its lexical scope but it can still access ittest();
function outer(x){return function inner(y){return x+y;}}
像这样调用函数:
var add10 = outer(10);add10(20); // The result will be 30add10(40); // The result will be 50
var add20 = outer(20);add20(20); // The result will be 40add20(40); // The result will be 60
"use strict";
var foo = 1;var bar = 2;
function myFunc() {//-- Define local-to-function variablesvar a = 1;var b = 2;var foo = 3;}
//-- And then, call it:myFunc();
function A() {var x = 42;}
console.log(x);
// undefined
从盒子外面,你看不到盒子里面是什么。
但是从盒子里面,你可以看到盒子外面的东西:
var x = 42;
function A() {console.log(x);}
// 42
在函数A内部,您有x的“范围访问”。
现在,如果你有两个盒子并排:
function A() {var x = 42;}
function B() {console.log(x);}
// undefined
在函数B内部,您无法访问函数A内部的变量。
但是如果你把定义函数B放在函数A里面:
function A() {
var x = 42;
function B() {console.log(x);}
}
// 42
您现在拥有“范围访问”。
函数
在JavaScript中,您可以通过调用它来运行函数:
function A() {console.log(42);}
像这样:
A();
// 42
函数作为值
在JavaScript中,您可以将标记指向函数,就像指向数字一样:
var a = function() {console.log(42);};
变量a现在表示一个函数,您可以运行它。
a();// 42
你也可以传递这个变量:
setTimeout(a, 1000);
在一秒钟(1000毫秒)内,函数a指向被调用:
// 42
关闭范围
现在,当您定义函数时,这些函数可以访问它们的外部作用域。
当您将函数作为值传递时,如果该访问丢失将很麻烦。
在JavaScript中,函数保持对外部作用域变量的访问。即使它们被传递到其他地方运行。
var a = function() {
var text = 'Hello!'
var b = function() {console.log(text);// inside function `b`, you have access to `text`};
// but you want to run `b` later, rather than right awaysetTimeout(b, 1000);
}
现在怎么办?
// 'Hello!'
或者考虑这个:
var c;
var a = function() {
var text = 'Hello!'
var b = function() {console.log(text);// inside function `b`, you have access to `text`};
c = b;
}
// now we are out side of function `a`// call `a` so the code inside `a` runsa();
// now `c` has a value that is a function// because what happened when `a` ran
// when you run `c`c();
// 'Hello!'
var tellStoryOfPinocchio = function(original) {
// Prepare for exciting things to happenvar pinocchioFindsMisterGeppetto;var happyEnding;
// The story starts where Pinocchio searches for his 'father'var pinocchio = {name: 'Pinocchio',location: 'in the sea',noseLength: 2};
// Is it a dog... is it a fish...// The dogfish appears, however there is no such concept as the belly// of the monster, there is just a monster...var terribleDogfish = {swallowWhole: function(snack) {// The swallowing of Pinocchio introduces a new environment (for the// things happening inside it)...// The BELLY closure... with all of its guts and attributesvar mysteriousLightLocation = 'at Gepetto\'s ship';
// Yes: in my version of the story the monsters mouth is directly// connected to its belly... This might explain the low ratings// I had for biology...var mouthLocation = 'in the monsters mouth and then outside';
var puppet = snack;
puppet.location = 'inside the belly';alert(snack.name + ' is swallowed by the terrible dogfish...');
// Being inside the belly, Pinocchio can now experience new adventures inside itpinocchioFindsMisterGeppetto = function() {// The event of Pinocchio finding Mister Geppetto happens inside the// belly and so it makes sence that it refers to the things inside// the belly (closure) like the mysterious light and of course the// hero Pinocchio himself!alert(puppet.name + ' sees a mysterious light (also in the belly of the dogfish) in the distance and swims to it to find Mister Geppetto! He survived on ship supplies for two years after being swallowed himself. ');puppet.location = mysteriousLightLocation;
alert(puppet.name + ' tells Mister Geppetto he missed him every single day! ');puppet.noseLength++;}
happyEnding = function() {// The escape of Pinocchio and Mister Geppetto happens inside the belly:// it refers to Pinocchio and the mouth of the beast.alert('After finding Mister Gepetto, ' + puppet.name + ' and Mister Gepetto travel to the mouth of the monster.');alert('The monster sleeps with its mouth open above the surface of the water. They escape through its mouth. ');puppet.location = mouthLocation;if (original) {alert(puppet.name + ' is eventually hanged for his innumerable faults. ');} else {alert(puppet.name + ' is eventually turned into a real boy and they all lived happily ever after...');}}}}
alert('Once upon a time...');alert('Fast forward to the moment that Pinocchio is searching for his \'father\'...');alert('Pinocchio is ' + pinocchio.location + '.');terribleDogfish.swallowWhole(pinocchio);alert('Pinocchio is ' + pinocchio.location + '.');pinocchioFindsMisterGeppetto();alert('Pinocchio is ' + pinocchio.location + '.');happyEnding();alert('Pinocchio is ' + pinocchio.location + '.');
if (pinocchio.noseLength > 2)console.log('Hmmm... apparently a little white lie was told. ');}
tellStoryOfPinocchio(false);
function getA() {var a = [];
// this action happens later,// after the function returned// the `a` valuesetTimeout(function() {a.splice(0, 0, 1, 2, 3, 4, 5);});
return a;}
var a = getA();out('What is `a` length?');out('`a` length is ' + a.length);
setTimeout(function() {out('No wait...');out('`a` length is ' + a.length);out('OK :|')});
var closure = createclosure(varForClosure);closure(param1); // closure has access to whatever createclosure gave it access to,// including the parameter storing varForClosure.
vs
var contextvar = varForClosure; // use a struct for storing more than one..contextclosure(contextvar, param1);
vs
var contextobj = new contextclass(varForClosure);contextobj->objclosure(param1);
// let say we can only use a traditional for loop, not the forEach
for (var i = 0; i < 10; i++) {
setTimeout(function() {console.log('without closure the visited index - '+ i)})}
// this will print 10 times 'visited index - 10', which is not correct
/**Expected output is
visited index - 0visited index - 1...visited index - 9
**/
// we can solve it by using closure concept//by using an IIFE (Immediately Invoked Function Expression)
// --- updated code ---
for (var i = 0; i < 10; i++) {(function (i) {setTimeout(function() {console.log('with closure the visited index - '+ i)})})(i);}
function newCounter() {var counter = 0;return function increment() {counter += 1;}}
var counter1 = newCounter();var counter2 = newCounter();
counter1(); // Number of events: 1counter1(); // Number of events: 2counter2(); // Number of events: 1counter1(); // Number of events: 3
var pure = function pure(x){return x// only own environment is used}
var foo = "bar"
var closure = function closure(){return foo// foo is free variable from the outer environment}
function showName (firstName, lastName) { var nameIntro = "Your name is ";// this inner function has access to the outer function's variables, including the parameterfunction makeFullName () { return nameIntro + firstName + " " + lastName; } return makeFullName (); } showName ("Michael", "Jackson"); // Your name is Michael Jackson
$(function() { var selections = [];$(".niners").click(function() { // this closure has access to the selections variableselections.push (this.prop("name")); // update the selections variable in the outer function's scope});});
function celebrityName (firstName) {var nameIntro = "This celebrity is ";// this inner function has access to the outer function's variables, including the parameterfunction lastName (theLastName) {return nameIntro + firstName + " " + theLastName;}return lastName;}var mjName = celebrityName ("Michael"); // At this juncture, the celebrityName outer function has returned.// The closure (lastName) is called here after the outer function has returned above// Yet, the closure still has access to the outer function's variables and parametermjName ("Jackson"); // This celebrity is Michael Jackson
function celebrityID () {var celebrityID = 999;// We are returning an object with some inner functions// All the inner functions have access to the outer function's variablesreturn {getID: function () {// This inner function will return the UPDATED celebrityID variable// It will return the current value of celebrityID, even after the changeTheID function changes itreturn celebrityID;},setID: function (theNewID) {// This inner function will change the outer function's variable anytimecelebrityID = theNewID;}}}var mjID = celebrityID (); // At this juncture, the celebrityID outer function has returned.mjID.getID(); // 999mjID.setID(567); // Changes the outer function's variablemjID.getID(); // 567: It returns the updated celebrityId variable
function createCar(){var rawMaterial = [/* lots of object */];function transformation(rawMaterials){/* lots of changement here */return transformedMaterial;}var transformedMaterial = transformation(rawMaterial);function assemblage(transformedMaterial){/*Assemblage of parts*/return car;}return assemblage(transformedMaterial);}
function init() {var name = 'Mozilla'; // name is a local variable created by initfunction displayName() { // displayName() is the inner function, a closurealert(name); // use variable declared in the parent function}displayName();}init();
function init() {var name = "Mozilla"; // name is a local variable created by initfunction displayName() { // displayName() is the inner function, a closurealert (name); // displayName() uses variable declared in the parent function}displayName();}init();
function showName(firstName, lastName) {var nameIntro = "Your name is ";// this inner function has access to the outer function's variables, including the parameterfunction makeFullName() {return nameIntro + firstName + " " + lastName;}return makeFullName();}
console.log(showName("Michael", "Jackson")); // Your name is Michael Jackson
$(function() {var selections = [];$(".niners").click(function() { // this closure has access to the selections variableselections.push(this.prop("name")); // update the selections variable in the outer function's scope});});