首页 > 编程 > JavaScript > 正文

Javascript闭包

2019-11-14 09:47:28
字体:
来源:转载
供稿:网友

概念

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 0counter.increment();counter.increment();console.log(counter.value()); // logs 2counter.decrement();console.log(counter.value()); // logs 1

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

更多MDN


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表