zoukankan      html  css  js  c++  java
  • 【巩固】JS中的封闭空间

    封闭空间的主要思想在于:

    • JS中给一个变量外面加小括号,是不改变任何结果的。比如
    var show = function(){ //定义一个名字为show的函数
    alert(12);
    };
    show(); //调用名字为show的函数

    上面的show()也可以写成(show)(),然后因为show本身又代表function(){alert(12);};,所以左边括号里的show完全可以用函数本身代替而写成(function(){alert(12);})()。而右边的括号里可以传参数。 
    这样做的好处至少有:

    • 可以在定义函数的同时又可以执行它,省去命名的步骤;
    • 封闭空间里定义的变量是这个空间里的局部变量。 
      看下面这个典型错误的选项卡例子,是运用封闭空间来解决for循环里事件函数里i的问题
    for (var i=0; i<aBtn.length; i++) {
    aBtn[i].onclick = function(){
    for (var i=0; i<aBtn.length; i++) {
    aBtn[i].className = '';
    aDiv[i].style.display = 'none';
    }
    this.className = 'active';
    aDiv[i].style.display = 'block'; //这行的i就是有问题的,因为在没有点击aBtn[i]之前而执行里面代码的时候i早就变成了3,而不是我们要的每次循环得到的那个i
    };
    }

    上述代码是错的,可以想到,如果for循环里的代码如果是一个函数执行,那函数执行就能和for循环同步执行,每次循环i,只要把i传进里面函数的参数里,就能保证同时递增(严格来讲也不是同步,这个以后再说)。所以完全可以用封闭空间的方式来直接执行函数,并把i当做参数传进封闭空间函数即可。

    for (var i=0; i<aBtn.length; i++) {
    (function(index){ //在定义的时候就要求传一个index变量
    aBtn[i].onclick = function(){
    for (var i=0; i<aBtn.length; i++) {
    aBtn[i].className = '';
    aDiv[i].style.display = 'none';
    }
    this.className = 'active';
    aDiv[index].style.display = 'block'; //这里的index就相当于每次递增的i
    };
    })(i); //这里将每次递增的i传给封闭函数里的参数
    }

    上面的例子,最外层for循环里的代码是一个封闭空间函数,它在定义的同时就执行了,而且是通过传参的方式将每次递增的i传进了函数,所以可以每次执行i都不同。

    • 封闭空间的注意事项 
      一般在工作中,用封闭空间可以很好地避免变量重名的问题,比如下面这个例子
    //下面是员工A写的代码
    var oBtn = document.getElementsByTagName('input')[0];
    oBtn.onclick = function(){
    alert(oBtn.value);
    };
    //下面是员工B写的代码,但是他们2个人是分别在不同的文件里写的,而他也定义了oBtn,所以把前面的覆盖了
    var oBtn = document.getElementsByTagName('input')[1];
    oBtn.onclick = function(){
    alert(oBtn.value);
    };

    为了避免这样的情况出现,可以用封闭空间的方法,把各自的变量封闭为局部变量

    //下面是员工A写的代码
    ;(function(){
    var oBtn = document.getElementsByTagName('input')[0];
    oBtn.onclick = function(){
    alert(oBtn.value);
    };
    })();
    //下面是员工B写的代码
    ;(function(){
    var oBtn = document.getElementsByTagName('input')[1];
    oBtn.onclick = function(){
    alert(oBtn.value);
    };
    })();

    这时每个函数里的oBtn只在各自的函数里起作用。 
    另外每个(function()前加一个;的目的是,在实际工作中,不同人写不同的部分,最后会压缩在一个文件中,而这个;是为了防止前面的一个人写的代码忘了用;结束,而导致后面的代码出错,但是即使2个;;连在一起也不会有问题。

  • 相关阅读:
    【转载】 C#中使用Sum方法对List集合进行求和操作
    【转载】 C#中使用Count方法获取List集合中符合条件的个数
    【转载】C#使用FirstOrDefault方法快速查找List集合中符合条件的第一个实体
    【转载】Windows检测到IP地址冲突
    【转载】Asp.Net MVC网站提交富文本HTML标签内容抛出异常
    java笔试题(4)
    Android -- TouchEvent的分发和截获方式
    SQL优化
    Android -- 经验分享(二)
    设计模式(十二)外观模式(结构型)
  • 原文地址:https://www.cnblogs.com/bluefantasy728/p/5651794.html
Copyright © 2011-2022 走看看