Home >Web Front-end >JS Tutorial >A brief analysis of javascript closure (Closure) usage examples_javascript skills

A brief analysis of javascript closure (Closure) usage examples_javascript skills

WBOY
WBOYOriginal
2016-05-16 15:29:011122browse

The example in this article describes the usage of javascript closure (Closure). Share it with everyone for your reference, the details are as follows:

closure is translated as "closure", and I feel that this thing is packaged in a too academic way. Let’s briefly discuss it with reference to books and online resources (please pay attention to any inappropriate understanding).

1. What is closure

Official answer: The so-called "closure" refers to an expression (usually a function) that has many variables and an environment bound to these variables, so these variables are also part of the expression.

After reading the above definition, if you are not an expert, I firmly believe that you will ask angrily like me: Is this tmd human language?
To understand closures, code is the most convincing. Here is the code:

function funcTest()
{
 var tmpNum=100; //私有变量
 //在函数funcTest内定义另外的函数作为funcTest的方法函数
 function innerFuncTest(
 {
    alert(tmpNum); //引用外层函数funcTest的临时变量tmpNum
 }
 return innerFuncTest; //返回内部函数
}
//调用函数
var myFuncTest=funcTest(); 
myFuncTest();//弹出100

In the above code, the comments have been written clearly. Now we can understand "closure" like this: define another function in the function body as the method function of the target object (in the example, define another function innerFuncTest as the method function of funcTest within the function funcTest), and the method function of this object is the opposite. Come to reference the temporary variables in the outer function body (closure is a mechanism to indirectly maintain variable values. In the example, the inner function innerFuncTest refers to the temporary variable tmpNum of the outer function funcTest. It must be noted here that temporary variables can be included in the outer function. all declared local variables, parameters, and other declared internal functions). When one of these inner functions is called outside the outer function that contains them, a closure is formed (in the example, when calling the function, myFuncTest actually calls the innerFuncTest function, which means that an inner function of funcTest, innerFuncTest is called outside funcTest, a closure is created).

2. Two examples of using closures

Here are two examples. One is because closures cause problems, and the other uses closures to cleverly bind parameters through the scope of a function.

The HTML markup fragments related to these two examples are as follows:

<a href="#" id="closureTest0">利用闭包的例子(1秒后会看到提示)</a><br />
<a href="#" id="closureTest1">由于闭包导致问题的例子1</a><br />
<a href="#" id="closureTest2">由于闭包导致问题的例子2</a><br />
<a href="#" id="closureTest3">由于闭包导致问题的例子3</a><br />

(1) Problems caused by closures

There are 4 3499910bf9dac5ae3c52d5ede7383485 elements in the above HTML tag fragment. Now we need to assign event handlers to the last three so that they report their order in the page when the user clicks. For example: when the user clicks When linking to the 2nd link, it reports "You clicked on the 1st link". To do this, if you write the following function that adds event handlers for the last three links:

function badClosureExample(){
  for (var i = 1; i <4; i++) {
    var element = document.getElementById('closureTest' + i);
    element .onclick = function(){
      alert('您单击的是第' + i + '个链接');
    }
  }
}

Then, call this function after the page is loaded (otherwise an error may be reported):

window.onload = function(){
  badClosureExample();
}

Look at the running results. If you click on the last three links, what information will you see in the warning box? ——It's all "You clicked on the 4th link". Does it surprise you? Why?

Analysis: Because the event handler assigned to element.onclick in the badClosureExample() function, that is, the onclick anonymous function is only called after the badClosureExample() function completes (when the user clicks the link). When calling, the variable i needs to be evaluated. The parser will first search inside the event handler, but i is not defined. Then, search in the badClosureExample() function. It is defined at this time, but the value of i is 4 (the for loop will stop executing only if i is greater than 4). Therefore, that value is obtained - exactly what the closure (anonymous function) would do if it were to use a variable in the scope of its outer function (badClosureExample). Moreover, this is also caused by the fact that the anonymous function itself cannot pass parameters (and therefore cannot maintain its own scope).

So how to solve the problem in this example? In fact, there are many methods (you might as well write it yourself and see). I think the code is relatively simple and direct:

function popNum(oNum){
  return function(){
          alert('您单击的是第'+oNum+'个链接');
  }
}
function badClosureExample(){
  for (var i = 1; i <4; i++) {
    var element = document.getElementById('closureTest' + i);
    element .onclick =new popNum(i);
    }
}

(2), clever use of closures to bind parameters

Still with the above HTML fragment, we want to delay popping up a warning box when the user clicks the first link. How to achieve this? The answer is to use the setTimeout() function, which calls a function after a specified number of milliseconds, such as:

Copy code The code is as follows:
setTimeout(someFunc,1000);

But the problem is that parameters cannot be passed to someFunc function. This problem can be easily solved using closures:
function goodClosureExample(oMsg){
  return function(){
    alert(oMsg);
  };
}

The function goodClosureExample is used to return an anonymous function (closure). And we can make the returned anonymous function bind the parameter by passing it a parameter, such as:

Copy code The code is as follows:
var good = goodClosureExample('This parameter is bound through a closure');

而此时,就可以将绑定了参数的good函数传递给setTimeout()实现延时警告了:
复制代码 代码如下:
setTimeout(good,1000) //此时good中已经绑定了参数

最后,测试通过的完整代码:
window.onload = function(){
  var element = document.getElementById('closureTest0');
  if (element) {
    var good = goodClosureExample('这个参数是由闭包绑定的');
    element.onclick = function(){
      setTimeout(good, 1000); //延迟1秒弹出提示
    }
  }
}

3、javascript的垃圾回收原理

(1)、在javascript中,如果一个对象不再被引用,那么这个对象就会被GC回收;

(2)、如果两个对象互相引用,而不再被第3者所引用,那么这两个互相引用的对象也会被回收。

在js中使用闭包,往往会给javascript的垃圾回收器制造难题。尤其是遇到对象间复杂的循环引用时,垃圾回收的判断逻辑非常复杂,搞不好就有内存泄漏的危险,所以,慎用闭包。ms貌似已经不建议使用闭包了。

希望本文所述对大家JavaScript程序设计有所帮助。

Statement:
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