Home > Web Front-end > JS Tutorial > Understanding javascript closures_javascript skills

Understanding javascript closures_javascript skills

WBOY
Release: 2016-05-16 16:06:16
Original
1118 people have browsed it

1. First we need to know the variable scope chain

There are two types of scopes of variables: global variables and local variables. Variables that are not defined in any function are global variables, and variables defined in a function are local variables. Note that you must use the var keyword when defining variables inside a function. Variables without the var keyword are global variables.

Every piece of code in JavaScript has an associated scope chain. This scope chain is a list of objects or a linked list that defines the variables in the "scope" of this piece of code. The scope of the top-level code consists of global variables; the scope chain that does not include nested functions has two objects: one is the object of the defined function parameters and local variables, and the other is the global variable object; and the scope of the nested function The chain has three objects: function parameters and local variables - parameters of external functions and local variables - global variables. Functions can access objects on the scope chain, so functions can access global variables, but not the other way around, that is, local variables within a function cannot be accessed from outside the function.

var a=1;
function wai(){
  alert(a);        
  var m=10;
  n=20;
}

wai();          //=> 1; 函数内部可以访问全局变量
alert(m);        //=> error; 外部访问函数局部变量报错  
alert(n);        //=> 20; 函数内部定义的变量未使用var关键字,所以是全局变量,外部可以访问
Copy after login

2. How to read local variables externally

Sometimes, we need to access local variables within a function from the outside. In this case, we need to use a workaround. We use the characteristics of JavaScript variable scope to define sub-functions inside the function, and the sub-function can access the variables in the parent function

function wai(){
 var m=10;
  function nei(){
    alert(m); 
 }
  return nei;
}

var f = wai();
nei();              //=> error; nei()函数是一个局部变量,在外部不能访问
f();               //=> 10;
Copy after login

3. Closure

The nei() function in the previous code is a closure. As can be seen from the above, a closure is a function that can read the local variables inside the function. It is a function defined inside the function. In essence, it can be considered as the function inside and outside the function. Bridges that connect the exteriors together.

Closures have two functions:

First, as mentioned earlier, you can read the variables inside the function

Second, these local variables can be stored in memory to realize variable data sharing

function wai(){
  var m=99;
  function nei(){
    alert(m);
    m++;
  }
  return nei;
}
      
var f= wai();
f();         //=> 99;
f();         //=> 100;
f();         //=> 101;
Copy after login

In the above example, when the wai() function is running, the variable m is saved in the memory. The value of m can be read by executing f(), but direct alert(m) cannot!

We can also pass parameters to the closure function. As shown in the following example, an anonymous function is defined and a closure function is returned. The function adds the passed parameters to the local variable i in the anonymous function, and Make i increment;

var wai=(function(){
  var i=0;
  return function(num){
    num+=i;
    alert(num);
    i++;
 }
})();
wai(1);//1
wai(2);//3
wai(3);//5
Copy after login

To understand closures more deeply, let’s look at the following example:

Now I want to define a function that returns an array, and each element of the array is a function, and each function will pop up the corresponding index value

We might write like this

function box(){
 var arr=[];
  for(i=0;i<5;i++){
    arr[i]=function(){return i;}
  }
 return arr;  
}
var a=box();
alert(a);        //=>包含五个函数体的数组
alert(a[0]());     //=> 5;
alert(a[1]());    //=> 5;
Copy after login

The above code finds that all the pop-ups are 5, not 0,1,2,3,4 as we expected. This is because i is also a local variable that exists in memory. When we run a[0]() At the time, the value of i is already 5, and the value of i continues to increase during the entire running process of the box() function.

Solution: Implementation of closures

function box(){
var arr=[];
    for(var i=0;i<5;i++){

         arr[i]=(function(num){
           return function(){return num;}
         })(i);

     }
return arr;     
}

var arr=box();

for(var i=0;i<5;i++){

  alert(arr[i]());//0,1,2,3,4
}
Copy after login

4. Things to note when using closures

1) Since closures will cause the variables in the function to be stored in memory, which consumes a lot of memory, closures cannot be abused, otherwise it will cause performance problems on the web page, and may lead to memory leaks in IE. The solution is to delete all unused local variables before exiting the function.

2) The closure will change the value of the variable inside the parent function outside the parent function. Therefore, if you use the parent function as an object, the closure as its public method, and the internal variables as its private value, you must be careful not to Feel free to change the variable values ​​of the parent function.

5. Here are some questions about closures

If you can understand the results of the following code, you should understand the operation mechanism of closures.

Js code

var name = "The Window"; 
var object = { 
  name : "My Object", 
  getNameFunc : function(){ 
    return function(){ 
      return this.name;       //=>嵌套函数的this为全局变量或undefined,不会继承父函数的this
    }; 
  } 
}; 
alert(object.getNameFunc()()); //The Window
Copy after login

The reason why the above output is "The window" is because this in the nested function does not inherit the parent function this, and its value is a global variable or undefined (under ECMAScript5), so what is returned is the name variable of the global object. If you want it to return the name attribute of object, the code is as follows:

var name = "The Window"; 
   var object = { 
    name : "My Object", 
    getNameFunc : function(){ 
      var cur=this;
      return function(){ 
        return cur.name;
      }; 
    } 
  }; 
  alert(object.getNameFunc()()); //=》My Object
Copy after login

The above code assigns this of the parent function object to the cur variable, and its nested function can access its properties through the cur variable

-------------------------------------------------- -------------------------------------------------- -----
JavaScript closure example

function outerFun()
{
var a=0;
function innerFun()
{
a++;
alert(a);
} 
}
innerFun();  //=>error
Copy after login

The above code is wrong. The scope of innerFun() is inside outerFun(), and it is wrong to call it outside outerFun().

is changed to the following, which is a closure:

Js code

function outerFun()
{
   var a=0;
  function innerFun()
  {
    a++;
    alert(a);
  }
  return innerFun; //注意这里
}
var obj=outerFun();
obj(); //结果为1
obj(); //结果为2
var obj2=outerFun();
obj2(); //结果为1
obj2(); //结果为2
Copy after login

什么是闭包:

当内部函数 在定义它的作用域 的外部 被引用时,就创建了该内部函数的闭包 ,如果内部函数引用了位于外部函数的变量,当外部函数调用完毕后,这些变量在内存不会被 释放,因为闭包需要它们.

--------------------------------------------------------------------------------------------------------

再来看一个例子

Js代码

function outerFun()
{
   var a =0;
   alert(a); 
}
var a=4;
outerFun();   //=> 0
alert(a);      //=> 4
Copy after login

结果是 0,4 . 因为在函数内部使用了var关键字 维护a的作用域在outFun()内部.

再看下面的代码:

Js代码

function outerFun()
{
//没有var 
a =0;
alert(a); 
}
var a=4;
outerFun();    //=> 0
alert(a);      //=> 0
Copy after login

结果为 0,0 真是奇怪,为什么呢?

作用域链是描述一种路径的术语,沿着该路径可以确定变量的值 .当执行a=0时,因为没有使用var关键字,因此赋值操作会沿着作用域链到var a=4; 并改变其值.

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template