zoukankan      html  css  js  c++  java
  • 当闭包遇上for

      看看这个函数先:

          function fun1(x) {

            var a = x;   //a为局部变量

            function fun2() {

              return a;

             }

             return fun2;

            }

          var fun3 = fun1(10);

          var fun4 = fun1(9);

          alert(fun4()); //9

          alert(fun3()); //10

          a = 99;     //此时的a定义在全局环境下

          alert(fun3()); //10

      看出来没?fun3与fun4其实是通过闭包函数绑定了fun1的局部私有变量,同时fun3与fun4其实引用的闭包是不同的,但在内存合理分配的角度上看,更准确的说fun3与fun4的区别在于引用同一闭包函数时传入闭包函数的参数值是不同的,也就是说,我们可以通过参数来看函数的执行。

      我们可以这样说:fun3是存储了a为10的引用的闭包调用,fun4是存储了a为9的引用的闭包调用。

    所以,以下的输出就不难理解了:

      window.onload = function(){

        var oUl = document.getElementsByTagName("ul");

        var aLi = oUl.getElementsByTagName("li");

        var l = aLi.length;

        for( i =l - 1 ; i >= 0 ; i--){    

          aLi[i].onclick = function (){

            alert(i);

        }

      }

      此时点击li的结果都是弹出aLi.length的值,假设aLi.length为4,分析如下~

      原因是:js中,函数可通过调用而在不同时刻执行,时间由我们定,但对于for,if等流程控制语句其实是逐行进行的,也就是说当点击li触发onclick函数时,for循环已经结束,此时i值为4,所以点击时传入闭包的值为4,也就是说此时传入要调用的闭包的变量值为4,所以结果皆为4。我们之所以会有疑惑,大部分都是因为觉得传入的参数是aLi[i]中的i,其实此时传入的是for执行完时的 i 的引用;

      我是这样想的,通过for给aLi标序并添加onclick存放参数值为 i 的闭包的引用,此时传入的 i 为全局变量,for执行结束,i 为4,所以要为各li 在局部锁定相应 i 值,才能输出想要的结果,这时就要利用到闭包的特性了。

      看看怎么解决吧:

        window.onload = function(){

          var oUl = document.getElementsByTagName("ul");

          var aLi = oUl.getElementsByTagName("li");

          var l = aLi.length;

           for( i =l - 1 ; i >= 0 ; i--){

              aLi[i].onclick = function (a){

                  return function(){

                    alert(a);

                  }

               }(i);

           }

        }

      将aLi[i]的 i 当为参数传入内部函数,也就是说将 i 当做参数通过function (a)中的a传入return出来的闭包,此时alert(a);中的a与传入的 i 同值。实现了“绑定”,得到了想要的结果~

      当然,问题的解决方法往往不止一个,分清楚希望传入闭包的变量是什么往往可以更快的找到解决方案。

      

      

  • 相关阅读:
    MYSQL索引使用
    事务的概念是什么,有哪些基本属性?
    springboot和springmvc的区别
    List、Map、Set的区别与联系
    MyBatis-动态SQL
    MyBatis-映射文件
    MyBatis操作数据库及全局配置文件
    Jmeter的基本使用
    MySQL索引优化
    MySQL索引
  • 原文地址:https://www.cnblogs.com/pada/p/3654283.html
Copyright © 2011-2022 走看看