"Reprint" Easy to understand JS closure

Source: Internet
Author: User
Tags variable scope

Closures allow JavaScript programmers to write better code. Creative, expressive, and concise. We frequently use closures in JavaScript, and, no matter your JavaScript experience, you'll undoubtedly encounter them t IME and again. Sure, closures might appear complex and beyond your scope, but after your read this article, closures would be much more EAS Ily understood and thus more appealing for your everyday JavaScript programming tasks.

This was a relatively short (and sweet) post on the details of closures in JavaScript. You should is familiar with JavaScript variable scopes before you read further, because to understand closures you must und Erstand JavaScript ' s variable scope.

What is a closure?

A closure is A inner function, the have access to the outer (enclosing) function ' s variables-scope chain. The closure has three scope chains:it have access to their own scope (variables defined between its curly brackets), it has Access to the outer function ' s variables, and it had access to the global variables.

The inner function has access not only to the outer function ' s variables, but also to the outer function ' s parameters. Note that the inner function cannot call the outer function ' s arguments object, however, even though it can call The outer function ' s parameters directly.

You create a closure by adding a function inside another function.

A Basic Example of Closures in JavaScript:?
1 functionShowName (FirstName, lastName) {?2?varNameintro = "Your name is";3     //This inner function have access to the outer function ' s variables, including the parameter?4?functionmakefullname () {? 5?returnNameintro + firstName + "" +lastName;? 6     }7 ?8?returnmakefullname ();?9 }?Ten ? OneShowName ("Michael", "Jackson");//Your name is Michael Jackson?

Closures is used extensively in node. js; They is workhorses in node. js ' asynchronous, non-blocking architecture. Closures is also frequently used in jQuery and just on every piece of JavaScript code you read.

A Classic jQuery Example of Closures:?

1$(function() {2 ?3?varSelections = []; 4$ (". Niners"). Click (function() {//This closure have access to the selections variable?5Selections.push ( This. Prop ("name"));//Update the selections variable in the outer function ' s scope?6     });7 ?8});
Closures ' Rules and Side Effects
    • Closures has access to the outer function ' s variable even after the outer function returns

One of the most important and ticklish features with closures are that the inner function still have access to the outer fun Ction ' s variables even after the outer function has returned. YEP, you read that correctly. When functions in JavaScript execute, they use the same scope chain that is in effect when they were created. This means. Even after the outer function has returned, the inner function still have access to the outer function ' s VA Riables. Therefore, you can call the inner function later on your program. This example demonstrates:

  

1 functionCelebrityname (firstName) {2     varNameintro = "This celebrity is";3     //This inner function have access to the outer function ' s variables, including the parameter?4    functionLastName (thelastname) {5         returnNameintro + firstName + "" +Thelastname;6     }7     returnLastName;8 }9 ?Ten?varMjname = Celebrityname ("Michael");//at this juncture, the celebrityname outer function has returned.? One ? A?//The closure (LastName) is called here after the outer function has returned above? -?//yet, the closure still have access to the outer function ' s variables and parameter? -Mjname ("Jackson");//This celebrity is Michael Jackson?

    • Closures store references to the outer function ' s variables

They do not store the actual value.? Closures get more interesting when the value of the outer function ' s variable changes before, the closure is called. And this powerful feature can is harnessed in creative ways, such as this private variables example first demonstrated by Douglas Crockford:

  

1 functionCelebrityid () {2     varCelebrityid = 999;3     //We are returning a object with some inner functions?4     //All the inner functions has access to the outer function ' s variables?5     return {6GetID:function ()  {7             //This inner function would return the UPDATED Celebrityid variable?8             //it would return the current value of Celebrityid, even after the Changetheid function changes it?9           returnCelebrityid;Ten         }, OneSetID:function(thenewid) { A             //This inner function would change the outer function ' s variable anytime? -Celebrityid =Thenewid; -         } the     } - } - varMjid = Celebrityid ();//at this juncture, the Celebrityid outer function has returned.? -Mjid.getid ();//999? +Mjid.setid (567);//changes the outer function ' s variable? -Mjid.getid ();//567:it Returns the updated Celebrityid variable?

    • Closures Gone Awry

Because closures has access to the updated values of the outer function ' s variables, they can also leads to bugs when the Outer function ' s variable changes with a For loop. Thus:

  

1 //This example was explained in detail below (just after this code box).2?functionCelebrityidcreator (thecelebrities) {3     vari;4     varUniqueID = 100;5      for(i = 0; i < thecelebrities.length; i++) {6thecelebrities[i]["id"] =function ()  {7         returnUniqueID +i;8       }9     }    Ten     returnthecelebrities; One } A ? -?varActioncelebs = [{name: "Stallone", id:0}, {name: "Cruise", id:0}, {name: "Willis", id:0}]; - ? the?varCreateidforactioncelebs =Celebrityidcreator (actioncelebs); - ? -?varStalloneid = createidforactioncelebs [0];?? Console.log (Stalloneid.id ());//103

In the preceding example, by the time the anonymous functions was called, the value of I is 3 (the length of the array and then it increments). The number 3 is added to the UniqueID to create 103 for all the celebritiesid. So every position in the returned array get id = 103, instead of the intended 100, 101, 102.

The reason this happened is because, as we have a discussed in the previous example, the closure (the anonymous function in This example) have access to the outer function ' s variables by reference, not by value. So just as the previous example showed then we can access the updated variable with the closure, this example similarly AC cessed the I variable when it is changed, since the outer function runs the entire for loops and returns the last value of I, which is 103.

To fix the side effect (bug) in closures, you can use an Immediately invoked Function Expression (iife), such as The following:

1 functionCelebrityidcreator (thecelebrities) {2     vari;3     varUniqueID = 100;4      for(i = 0; i < thecelebrities.length; i++) {5thecelebrities[i]["id"] =function(j) {//The J parametric variable is the I-passed in on invocation of this iife?6             return function () {7                 returnUniqueID + j;//Each iteration of the in loop passes the current value of I into this iife and it saves the correct value to the ARR Ay?8} ()//by adding () at the end of this function, we is executing it immediately and returning just the value of UniqueID + J, instead of returning a function.?9} (i);//immediately invoke the function passing the I variable as a parameter?Ten     } One ? A     returnthecelebrities; - } - ? the?varActioncelebs = [{name: "Stallone", id:0}, {name: "Cruise", id:0}, {name: "Willis", id:0}]; - ? -?varCreateidforactioncelebs =Celebrityidcreator (actioncelebs); - ? +?varStalloneid = createidforactioncelebs [0]; -? Console.log (Stalloneid.id);//What's up ? + ? A?varCruiseid = Createidforactioncelebs [1];? Console.log (cruiseid.id);//101

"Reprint" Easy to understand JS closure

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.