资讯专栏INFORMATION COLUMN

再谈Js闭包

cuieney / 2346人阅读

摘要:不知不觉距离上一篇闭包文章已经过了个月了,现在的理解对比之前要健壮的多,再次总结下花生理解的闭包。这一段代码很重要,理解这一段代码基本上就可以说理解闭包了。

不知不觉距离上一篇闭包文章已经过了8个月了,现在的理解对比之前要健壮的多,再次总结下花生理解的闭包。

闭包实际上就是子作用域读取父作用域的变量,这本来很合理也很简单,但是关键点在于这个读取是动态的,请看下面的例子:

for(var i=0 ;i<3 ;i++){
    setTimeout(function(){
        console.log(i);
    });
};
// 输出 3 3 3

结果并不是期望的0 1 2,因为是动态的读取i,因此如果你在下文改变变量i也依旧会影响到输出读取i。

传统的解决方案是构建闭包,是最有效也是兼容性最好的方法

for(var i=0 ;i<3 ;i++){
    (function(num){
        setTimeout(function(){
            console.log(num);
        });
    })(i);
};
// 输出 0 1 2

这么做是十分有效的,为每一个闭包多带带创建一个作用域,也是下面要说的其他解决方案的基础。

这一段代码很重要,理解这一段代码基本上就可以说理解闭包了。

实际上,大多数情况我们并不是想单纯是使用for循环,for循环的一个很常见的用处是遍历数组。

var arr =["a" ,"b" ,"c"];
for(var i=0 ;i

因为是动态读取,所以输出undefined很正常。可以使用上面的构建一个自执行函数来解决,但还有一个更方便的解决方案,也是实际开发中经常用到的。

["a" ,"b" ,"c"].forEach(function(item){
    setTimeout(function(){
        console.log(item);
    });
});
// 输出 a b c

利用Array原生的forEach可以更好的实现,而且也符合语义,这个是花生最推荐的用法。

如果浏览器较新支持ES5,Function还提供一个bind方法来绑定参数

for(var i=0 ;i<3 ;i++){
    setTimeout(console.log.bind(null ,i));
};
// 输出 0 1 2

Function.bind具体的语法与兼容性可以参考MDN。

还有其他的“歪门邪道”的解决方案,比如利用闭包读取到父作用域的集合,在集合里寻找“自己”,或者是利用js的引用传递等等。

实际上,利用ES5的bind方法和Array的forEach就已经可以解决所有问题了,所以在实际开发中应该避免第一种构建闭包的解决方案。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80664.html

相关文章

  • 再谈闭包-词法作用域

    摘要:权威指南第六版关于闭包的说明采用词法作用域,也就是说函数的执行依赖于变量的作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的。闭包这个术语的来源指函数变量可以被隐藏于作用域链之内,因此看起来是函数将变量包裹了起来。 最近打算换工作,所以参加了几次面试(国内比较知名的几家互联网公司)。在面试的过程中每当被问起闭包,我都会说闭包是作用域的问题?令人惊讶的是几乎无一例外的当我提到...

    Ku_Andrew 评论0 收藏0
  • JS程序

    摘要:设计模式是以面向对象编程为基础的,的面向对象编程和传统的的面向对象编程有些差别,这让我一开始接触的时候感到十分痛苦,但是这只能靠自己慢慢积累慢慢思考。想继续了解设计模式必须要先搞懂面向对象编程,否则只会让你自己更痛苦。 JavaScript 中的构造函数 学习总结。知识只有分享才有存在的意义。 是时候替换你的 for 循环大法了~ 《小分享》JavaScript中数组的那些迭代方法~ ...

    melody_lql 评论0 收藏0
  • JS笔记

    摘要:从最开始的到封装后的都在试图解决异步编程过程中的问题。为了让编程更美好,我们就需要引入来降低异步编程的复杂性。异步编程入门的全称是前端经典面试题从输入到页面加载发生了什么这是一篇开发的科普类文章,涉及到优化等多个方面。 TypeScript 入门教程 从 JavaScript 程序员的角度总结思考,循序渐进的理解 TypeScript。 网络基础知识之 HTTP 协议 详细介绍 HTT...

    rottengeek 评论0 收藏0
  • JavaScript系列——JavaScript同步、异步、回调执行顺序之经典闭包setTimeou

    摘要:同步异步回调傻傻分不清楚。分割线上面主要讲了同步和回调执行顺序的问题,接着我就举一个包含同步异步回调的例子。同步优先回调内部有个,第二个是一个回调回调垫底。异步也,轮到回调的孩子们回调,出来执行了。 同步、异步、回调?傻傻分不清楚。 大家注意了,教大家一道口诀: 同步优先、异步靠边、回调垫底(读起来不顺) 用公式表达就是: 同步 => 异步 => 回调 这口诀有什么用呢?用来对付面试的...

    lewif 评论0 收藏0

发表评论

0条评论

cuieney

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<