Examples of Javascript closures _ javascript tips-js tutorial

Source: Internet
Author: User
Closure is the set of local variables of the function, but these local variables will continue to exist after the function returns. This article introduces the javascript closure through code examples, if you are interested in the knowledge of javascipt closures, join us. What is a closure?

What is a closure? The Closure is Closure, which is a new feature not available in static languages. However, closures are not complicated to be incomprehensible. In short, closures are:

Closure is the set of local variables of the function, but these local variables will continue to exist after the function returns.

The closure is the "stack" of the function, which is not released after the function is returned, we can also understand that these function stacks are not allocated on the stack, but allocated on the stack. When another function is defined in a function, the closure will be generated. The second definition above is the first supplementary description, the closure is the 'Local variable 'set of the function. This local variable can be accessed after the function returns. (This is not an official definition, but it should help you better understand the closure)

Understanding the closure of Javascript is critical. This article attempts to use the simplest example to understand this concept.

function greet(sth){  return function(name){    console.log(sth + ' ' + name);  }}//hi darrengreet('hi')('darren');

Or you can write it as follows:

var sayHi = greet('hi');sayHi('darren');


The question we want to raise is: why can the greet internal function use the variable "something?

Its internal operation is roughly as follows:

→ Create a global context
→ Execute the var sayHi = greet ('Hi'); statement to create the greet context, and save the variable "something" in the greet context.
→ Continue to execute the statements in the greet function and return an anonymous function. Although the greet context disappears from the stack, the something variable still exists in a certain memory space.
→ Continue to execute sayHi ('darren'); create the sayHi context and try to search for the th variable, but there is no th variable in the sayHi context. The sayHi context will find the memory corresponding to the something variable along a scope chain. An outer function is like a closure. Its internal function can use the variables of the external function.

A simple example of a closure

function buildFunctions(){  var funcArr = [];  for(var i = 0; i < 3; i++){    funcArr.push(function(){console.log(i)});  }  return funcArr;}var fs = buildFunctions();fs[0](); //3fs[1](); //3fs[2](); //3

Why are the results not 0, 1, or 2?

-- Because I acts as a closure variable and the current value is 3, it is used by internal functions. To achieve the desired effect, you can create an independent context during each traversal so that it is not affected by the closure. The self-triggered function can implement independent context.

function buildFunctions(){  var funcArr = [];  for(var i = 0; i < 3; i++){    funcArr.push((function(j){      return function(){       console.log(j);      };    }(i)));  }  return funcArr;}var fs = buildFunctions();fs[0](); //0fs[1](); //1fs[2](); //2

The two examples in this article reflect two aspects of the closure: one is that the internal function uses the closure variable, and the other is to write the internal function in the Self-triggered function to avoid being affected by the closure.

As a local variable, it can be accessed by the code in the function. This is no different from the static language. The difference between closure is that local variable can still be accessed by code outside the function after the function execution is complete. This means that the function must return a "Reference" pointing to the closure, or assign this "Reference" to an external variable to ensure that the partial variables in the closure are accessed by external code. Of course, the entity that contains this reference should be an object, because in Javascript, all objects except the basic types are left. Unfortunately, ECMAScript does not provide related members and methods to access the partial variation in the closure. However, in ECMAScript, the internal function () inner function defined in the function object is a local variable that can directly access external functions. Through this mechanism, we can access the closure in the following way.

Function greeting (name) {var text = 'hello' + name; // local variable // a closure is generated during each call and an internal function object is returned to the caller, returning function () {alert (text) ;}}var sayHello = greeting ("Closure"); sayHello () // access the local variable text through the Closure

The execution result of the above Code is: Hello Closure, because the sayHello () function can still access the local variable text defined within it after the greeting function is executed.

Well, this is the effect of closures in the legend. Closures have multiple application scenarios and patterns in Javascript, such as Singleton and Power Constructor.

ECMAScript Closure Model

How does ECMAScript implement closures? If you want to know more about it, you can obtain the ECMAScript specification for research. Here I will also give a simple explanation, the content also comes from the network.

When a function of ECMAscript script is run, each function Association has an Execution Context, which contains three parts.

The LexicalEnvironment)
The VariableEnvironment)
This binding

The third point of this binding is irrelevant to the closure, which is not discussed in this article. The variable identifier used to parse the function Execution Process in the grammar environment. We can think of a grammar environment as an object. This object contains two important components: Environment Recode and external reference ). The environment record contains the local variables and parameter variables declared inside the function. The external reference points to the context execution scenario of the external function object. In a global context scenario, the reference value is NULL. Such a data structure forms a one-way linked list. Each reference points to an outer context scenario.

For example, the closure model in the above example should be like this. The sayHello function is at the bottom layer, the greeting function is at the upper layer, and the global scenario is at the outermost layer. For example:

Therefore, when sayHello is called, sayHello will find the text value of the local variable in the context scenario, so "Hello Closure" is displayed in the dialog box on the screen"
The VariableEnvironment and The syntax environment have similar functions. For specific differences, see The ECMAScript standard document.

Example column of closure

I have a general understanding of what Javascript closures are and how closures are implemented in Javascript. The following examples help you better understand Closures. There are five examples in the following: JavaScript Closures For Dummies (image ).

Example 1: local variables in the closure are referenced rather than copied.

function say667() {  // Local variable that ends up within closure  var num = 666;  var sayAlert = function() { alert(num); }  num++;  return sayAlert;}var sayAlert = say667();sayAlert()

Therefore, the execution result should display 667 instead of 666.

Example 2: multiple functions are bound to the same closure because they are defined in the same function.

Function setupSomeGlobals () {// Local variable that ends up within closure var num = 666; // Store some references to functions as global variables extends tnumber = function () {alert (num);} gIncreaseNumber = function () {num ++;} gSetNumber = function (x) {num = x ;}} setupSomeGolbals (); // assign the value of effectnumber (); // 666 gIncreaseNumber (); effectnumber (); // 667 gSetNumber (12); // effectnumber (); // 12

Example 3: When a function is assigned in a loop, these functions are bound to the same closure.

function buildList(list) {  var result = [];  for (var i = 0; i < list.length; i++) {    var item = 'item' + list[i];    result.push( function() {alert(item + ' ' + list[i])} );  }  return result;}function testList() {  var fnlist = buildList([1,2,3]);  // using j only to help prevent confusion - could use i  for (var j = 0; j < fnlist.length; j++) {    fnlist[j]();  }}

The execution result of testList is three times that the item3 undefined window pops up, because the three functions are bound to the same closure and the item value is the final calculation result, but when I jumps out of the loop, the I value is 4, so the result of list [4] is undefined.

Example 4: All local variables of an external function are in the closure, even if the variable is declared after the definition of an internal function.

function sayAlice() {  var sayAlert = function() { alert(alice); }  // Local variable that ends up within closure  var alice = 'Hello Alice';  return sayAlert;}var helloAlice=sayAlice();helloAlice();

The execution result is displayed in the "Hello Alice" window. Even if the local variable is declared after the sayAlert function, the local variable can still be accessed.

Example 5: Create a new closure for each function call

function newClosure(someNum, someRef) {  // Local variables that end up within closure  var num = someNum;  var anArray = [1,2,3];  var ref = someRef;  return function(x) {    num += x;    anArray.push(num);    alert('num: ' + num +    '\nanArray ' + anArray.toString() +    '\nref.someVar ' + ref.someVar);  }}closure1=newClosure(40,{someVar:'closure 1'});closure2=newClosure(1000,{someVar:'closure 2'});closure1(5); // num:45 anArray[1,2,3,45] ref:'someVar closure1'closure2(-10);// num:990 anArray[1,2,3,990] ref:'someVar closure2'

Closure Application

Singleton:

var singleton = function () {  var privateVariable;  function privateFunction(x) {    ...privateVariable...  }  return {    firstMethod: function (a, b) {      ...privateVariable...    },    secondMethod: function (c) {      ...privateFunction()...    }  };}();

This single piece is implemented through the closure. The closure is used to encapsulate Private Members and methods. The anonymous main function returns an object. The object contains two methods: method 1 can be a private variable, and method 2 can be used to access internal private functions. Note that '()' is at the end of the anonymous main function. Without this '()', a single piece cannot be generated. Because the anonymous function can only return unique objects and cannot be called elsewhere. This is the method of using closures to generate a single piece.

Related Article

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.