JavaScript Closure example detailed _javascript tips

Source: Internet
Author: User
Tags closure function definition javascript closure example

What is closure

What is a closure? Closures are closure, a new feature that static languages do not have. But closures are not something that is too complex to be understood, in short, closures are:

Closures are the set of local variables of a function, except that these local variables continue to exist after the function returns.

The closure is just that the function's "stack" is not released after the function returns, we can also understand that these function stacks are not allocated on the stack, but are allocated on the heap. When you define another function within a function, a second definition is created that is the first supplemental description, the first of which is the main verb-the closure is a function ' Local variable ' collection. Only this local variable can be accessed after the function returns. (This is not an official definition, but this definition should be more beneficial to your understanding of closures)

Understanding JavaScript closures is critical, and this article attempts to understand this concept in the simplest case.

function greet (STH) {return
  function (name) {
    Console.log (sth + ' + name);
  }
}
Hi Darren
greet (' Hi ') (' Darren ');

Or it could be written like this:

var sayhi = greet (' Hi ');
Sayhi (' Darren ');


The question we want to ask is: Why do greet's internal functions use the STH variable?

Its internal operations are generally as follows:

→ Create global Context
→ execute var sayhi = greet (' Hi '); statement, create greet context, variable sth stored in greet context.
→ Continue executing the statement within the greet function, returning an anonymous function, although the greet context disappears from the stack, but the STH variable still exists in some space in memory.
→ Continue to execute sayhi (' Darren '), create the Sayhi context, and attempt to search for the STH variable, but there is no sayhi variable in this context of STH. The Sayhi context will find the memory corresponding to the STH variable along a scope chain. The outer function is like a closure, and its intrinsic functions can use variables of external functions.

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] (); 3
fs[1] ();//3
fs[2] ()//3

Above, why is the result not 0, 1, 2?

--because I as a closure variable, the current value is 3, is used by internal functions. To achieve the desired effect, you can create a separate context for each traversal at the time of traversal so that it is unaffected by the closure. and the self triggering function can implement the 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] (); 0
Fs[1] ();//1
fs[2] ()//2

The two examples in this article illustrate the 2 aspects of closure: one is that the internal function uses the closure variable, and the other is that the internal function is written in the trigger function to avoid being affected by the closure.

As local variables can be accessed by the code within the function, this and static language is no difference. The difference between closures is that local variables can be accessed by code outside the function at the end of the function execution. This means that the function must return a reference to the closure, or assign the reference to an external variable to ensure that the local variables in the closure are accessed by the external code. Of course the entity that contains this reference should be an object, because the rest of the basic type in JavaScript is the object. Unfortunately, ECMAScript does not provide relevant members and methods to access the local variables in the closure. However, in ECMAScript, the intrinsic function () inner function defined in the functional object is a local variable that can directly access the external function, and through this mechanism we can complete the access to the closure in the following way.

function greeting (name) {
   var text = ' Hello ' + name;//local variable
   //per call, produces closure and returns internal function object to caller return
   function () {alert (text);}
}
var sayhello=greeting ("Closure");
SayHello ()//access to local variable text via closure

The result of this code is: Hello Closure, because the SayHello () function can still access the local variable text defined within it after the greeting function has finished executing.

Well, this is the legendary closure effect, closures in JavaScript have a variety of application scenarios and patterns, such as Singleton,power constructor and other JavaScript patterns are inseparable from the use of closures.

ECMAScript closed-pack model

How does ECMAScript achieve closure? Want to know more about the pro can get ECMAScript specifications for research, I also only do a simple explanation, content is also from the network.

When a function of a ECMAScript script is run, each function association has an execution context scenario (Execution context), which contains three parts

Grammar environment (the lexicalenvironment)
Variable environment (the variableenvironment)
This binding

The 3rd this binding has nothing to do with closures and is not discussed in this article. The variable identifier used to resolve function execution in a grammar environment. We can imagine the grammatical environment as an object that contains two important components, environmental records (Enviroment Recode), and external references (pointers). An environment record contains local variables and parameter variables that contain internal declarations of functions, and external references point to context execution scenarios for external function objects. This reference value is NULL in the global context scenario. Such a data structure constitutes a one-way list of links, each of which points to the context scene of the outer layer.

For example, the closure model of our example above should be like this, the SayHello function is at the lowest level, the upper layer is the function greeting, the outermost layer is the global scene. The following figure:

So when SayHello is invoked, SayHello finds the local variable text value through the context scene, so the "Hello Closure" is displayed in the Screen dialog box.
The function of the variable environment (the variableenvironment) and the grammar environment are basically similar, and the specific differences refer to the ECMAScript documentation.

Closure of the sample column

I've got a rough idea of what JavaScript closures are, and how closures are implemented in JavaScript. Here are some examples to help you get a deeper understanding of closures, with a total of 5 examples from JavaScript Closures for Dummies (mirroring).

Example 1: A local variable in a closure is a reference rather than a copy

function say667 () {
  //local variable which ends up within closure
  var num = 666;
  var sayalert = function () {alert (num);}
  num++;
  return sayalert;
}
var Sayalert = say667 ();
Sayalert ()

So the execution result should pop up 667 instead of 666.

Example 2: Multiple functions bind to the same closure because they are defined within the same function.

function Setupsomeglobals () {
  //local variable which ends up within closure
  var num = 666;
  Store some references to functions as global variables
  galertnumber = function () {alert (num);}
  Gincreasenumber = function () {num++;}
  Gsetnumber = function (x) {num = x;}
}
Setupsomegolbals (); Three global variables are assigned
galertnumber ();//666
gincreasenumber ()
; Galertnumber (); 667
Gsetnumber (a);//
Galertnumber ();//12

Example 3: When assigning functions in a loop, these functions bind 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-to-help prevent confusion-could the use I for
  (var j = 0; J < Fnlist.length; + +) {
    fnlist[j] () ;
  }
}

The result of the testlist is to eject the item3 undefined window three times, because the three functions bind the same closure, and the value of item is the result of the last calculation, but when I jump out of the loop I value 4, so the result of list[4] is undefined.

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

function Sayalice () {
  var sayalert = function () {alert (Alice);}
  Local variable which ends up within closure
  var alice = ' Hello Alice ';
  return sayalert;
}
var helloalice=sayalice ();
Helloalice ();

The execution result is a window that pops up "Hello Alice". Local variables can still be accessed even after the local variable declaration is sayalert by the function.

Example 5: Create a new closure every time the function is called

function Newclosure (Somenum, someref) {//local variables-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 '

The application of closure package

Singleton single piece:

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 closures. The encapsulation of private members and methods is done through closures. The anonymous main function returns an object. The object contains two methods, Method 1 can be a private variable, and Method 2 accesses the internal private function. The place to note is the ' () ' where the anonymous main function ends, without which a single piece cannot be produced. Because an anonymous function can only return a unique object and cannot be invoked elsewhere. This is the use of closures to produce a single piece of the method.

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.