1

写了几个小例子揭示JS中闭包的本质,适合自己运行后分析。


HTML文件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Test</title>
    <script src="lib/jquery-3.1.0.js"></script>
    <script src="closure_example.js"></script>
</head>

<body>
    <button>0</button>
    <button>1</button>
    <button>2</button>
    <button>3</button>
    <button>4</button>
    <button>5</button>
    <button style="display:none" class="hide">什么是闭包</button>
</body>

</html>

JS代码

$(function () {


    /*
    给6个按钮绑定事件,点击打印按钮的序号
     */
    for (var i = 0; i < 6; i++) {
        $('button').eq(i).on('click', function () {
            console.log(i);
        });
    }

    /*
    解决方案一:借用DOM元素的属性存储序号i
     */
    for (var i = 0; i < 6; i++) {
        $('button').eq(i).attr('i', i).on('click', function () {
            console.log($(this).attr('i'));
        });
    }


    /*
    解决方案二:利用IIFE将i作为参数传递给内部函数
     */
    for (var i = 0; i < 6; i++) {
        (function (i) {
            $('button').eq(i).on('click', function () {
                console.log(i);
            });
        })(i);
    }

    /*
    错误方案:IIFE使用位置错误
     */
    for (var i = 0; i < 6; i++) {
        $('button').eq(i).on('click', function () {
            (function (i) {
                console.log(i);
            })(i);
        });
    }

    /*
    解决方案三:利用IIFE所创造的“块级作用域”,将i赋值给局部变量
    */
    for (var i = 0; i < 6; i++) {
        (function () {
            var temp = i;
            $('button').eq(temp).on('click', function () {
                console.log(temp);
            });
        })();
    }

    /*
    什么是闭包?
    */
    function closure() {
        var i = 0;
        return function fun() {
            i++;
            console.log(i);
        }
    }

    var foo = closure();
    foo();
    foo();
    foo();

    var bar = closure();
    bar();
    bar();
    bar();

    $('.hide').show().on('click', foo)

});

DiaryChris
63 声望2 粉丝

坚不可摧