Javascript闭包

    xiaoxiao2021-03-26  22

    #概念

    Javascript支持闭包(closure)的概念,Javascript里的闭包是一种特殊的对象,由函数和函数创建时所处的环境组成,环境里包括了闭包被创建时所在的作用域里的所有本地变量。

    function makeFunc() { var name = "Mozilla"; function displayName() { alert(name); } return displayName; } var myFunc = makeFunc(); myFunc();

    上例子中,myFunc就是闭包。

    #循环创建闭包引发的错误

    for (var i = 0; i < 10; i++) { function print() { console.log(i); } setTimeout(print, 1000); } //output: 10 10 10 10 10 10 10 10 10 10

    循环创建的闭包都关联到相同的变量i, 在第一个print执行时,i已经为10。

    为了解决这个问题,一个方法是使用更多的闭包

    for (var i = 0; i < 10; i++) { (function (i) { function print() { console.log(i); } setTimeout(print, 1000); }) (i); } for (var i = 0; i < 10; i++) { (function () { var ii = i; function print() { console.log(ii); } setTimeout(print, 1000); }) (); } for (var i = 0; i < 10; i++) { var print = (function () { var ii = i; return function print() { console.log(ii); } }) (); setTimeout(print, 1000); } //same output: 0 1 2 3 4 5 6 7 8 9

    上述不同的写法都是利用更多的闭包来创建独立的闭包环境,都有一样的结果。

    另一个方法时用ES6的let关键字声明变量:

    for (let i = 0; i < 10; i++) { function print() { console.log(i); } setTimeout(print, 1000); } //output: 0 1 2 3 4 5 6 7 8 9

    #模拟私有方法

    Javascript没有类似Java这里面向对象语言的方法访问权限的功能,不过通过闭包,可以模拟出私有方法:

    var counter = (function() { var privateCounter = 0; function changeBy(val) { privateCounter += val; } return { increment: function() { changeBy(1); }, decrement: function() { changeBy(-1); }, value: function() { return privateCounter; } }; })(); console.log(counter.value()); // logs 0 counter.increment(); counter.increment(); console.log(counter.value()); // logs 2 counter.decrement(); console.log(counter.value()); // logs 1

    counter.increment, counter.decrement, counter.value为公共的方法,共享同一个环境形成闭包,而counter内部privateCounter和changeBy则被私有化,对外不可见。这种做法提供了代码隐藏和封装的一些益处。

    更多MDN

    转载请注明原文地址: https://ju.6miu.com/read-659306.html

    最新回复(0)