javascript - 什么是封闭空间,使用封闭空间的意义何在?
天蓬老师
天蓬老师 2017-04-10 15:50:08
0
3
528

学习过用封闭空间写选项卡的实例后,对如下代码感到不知如何理解:

<script>
window.onload=function(){
    var oBox = document.getElementById('box');
    var aBtn = oBox.getElementsByTagName('input');
    var ap = oBox.getElementsByTagName('p');
    
    for(var i=0;i<aBtn.length;i++){
        (function (index){
            aBtn[index].onclick=function(){
                for(var i=0;i<aBtn.length;i++){
                    aBtn[i].className='';
                    ap[i].style.display='none';
                }
                this.className='on';
                ap[index].style.display='block';
            };
        })(i);
    }
};
</script>

我知道“在循环里加事件,事件里不能用i”这件事,但尚未想清楚为什么不能用?以及为什么利用封闭空间这种写法,能够解决这个问题?
希望有人能够通过这个例子,把封闭空间的本质和循环事件里不能用i原因的帮我理清楚

天蓬老师
天蓬老师

欢迎选择我的课程,让我们一起见证您的进步~~

全部回覆(3)
伊谢尔伦

你这个是IIFE(Immediately-Invoked Function Expression )

var a = '123';
(function(){
   var a = '321';
    console.log(a);
}());
console.log(a);

输出:

321
123

看个例子:

function addLinks () {
    for (var i=0, link; i<5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = function () {
            alert(i);
        };
        document.body.appendChild(link);
    }
}

你随便点击那个都会提示link 5, 为什么呢?因为,i是在循环里面定义的,等你真的触发onclick事件的时候,循环已经执行完了,这个时候i等于5,根本原因在于:JavaScript's scopes are function-level, not block-level,用IIFE的意义在于把循环时的变量传递传到IIFE中的匿名function中,形成它自己范围的一个新的变量。

function addLinks () {
    for (var i=0, link; i<5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = function (num) {
            return function () {
                alert(num);
            };
        }(i);
        document.body.appendChild(link);
    }
}

这个由点绕,自己多理解吧。


关于闭包,我实在不知道用中文如何描述,我用英语总结一下:

future reference to a outer scope variable creates a closure.
大致意思,对于一个外部变量的“未来引用”(事件处理器绑定的时候,事件处理器还没有被触发)会创建闭包。

when the outer function finish executing, variables in it's local scope are     discarded, so if inner functions need to use such variables in the future, they need to remember those variables.(in software manner, store in somewhere).

当一个外部方法执行完了之后,其本地变量就不复存在了,所以当这个方法里面的内部方法要在将来引用这些本该消失的变量时,就需要把这些变量记住,用编程的话来说,就是存在内存中的某个地方。

下面的代码,在chrome中打开,我们在第10行和第12行加上断点:

<html>
<body></body>
<script>
function addLinks () {
    for (var i=0, link; i<5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = function (num) {
            console.log(1);
            return function () {
                alert(num);
            };
        }(i);
        document.body.appendChild(link);
    }
}
addLinks();
</script>
</html>


i作为参数传递给匿名function内部变量num, 没有引用外部变量,没有闭包。


里面的匿名function,在未来运行的时候,要用到外部变量num,此时会创建闭包。

小葫芦

闭包的用法很多 网上随便搜一下一堆 面试笔试都喜欢考的东西
然而对于这种框架 如果用jQuery有更容易理解的写法 就是用data把数据全存在外层p上 每次用的时候去取
闭包毕竟有那么一点点内存泄露的危险

黄舟

最大的作用,防止全局名空间的污染

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!