美文网首页
求你了,别再黑闭包了

求你了,别再黑闭包了

作者: 时修七年 | 来源:发表于2017-11-09 21:34 被阅读5次

求你了,别再黑闭包了


声明:此文无意冒犯任何人,仅为个人学习总结,不适之处欢迎斧正。

引子

\\ Talk is cheap .show me the code.code never lie!NEVER

先看三段被称为js闭包经典面试题的代码

第一种引起for循环问题的原因

//  异步引起的for循环问题 1
    for(var i=0;i<5;i++){
      setTimeout(function timer(){
        console.log(i);
      },i*1000);

          
// 异步引起的for循环问题 2

for (var i = 1; i <= 5; i++) {
  item.onclick = function () {
    console.log(i);
  };
}

上面两段代码经常被拿来解释闭包,百度一下javaScript for循环"首屏中就会出来各种以“彻底弄懂js循环中的闭包问题 ”的博客,然而最后只是华丽丽的推给了闭包,总结起来就是“反正我已经告诉你了,这个问题就是闭包引起的”。

但是这两段代码中结果最终只输出5,真的和闭包没有一毛钱的关系。真正的原因是当给元素绑定事件或者设置定时器函数时就会形成异步;有因为javaScript语言是单线程语言(一次只执行一件事情,在当前事件尚未执行完之前,即使异步函数调用事件到了,也要先把当前的事情执行完);这两段代码开始执行后首先读取到for循环(声明并初始化i的值,对i的值进行判断)然后进入for循环体内,遇到异步函数,把异步函数加入到任务池(所有异步函数都会被到这里,等待立即执行代码执行过后再开始执行),然后一根筋的js继续执行for循环,直到i=5;不再满足for循环的执行条件,便开始执行任务池中的异步事件(即给item元素绑定事件)

第二种引起for循环问题的原因

\\函数作为值引起的for循环问题

for(var i=0,arr=[];i<5;i++){
  arr.push(function(){alert(i)});
}

arr[0]()

js中的函数有很多的身份,上面的代码中for循环执行后,每次执行arr.push()函数把匿名函数当作值(此时函数仅仅是一段字符串而已)添加到arr数组中,如此反复执行最终到i=5;for循环停止;在我们通过arr0语句调用它之前,它仅仅是一段字符串,根本不会和i变量产生任何关系(事实上此时i也是函数字符串中的一部分);当我们调用函数,匿名函数首先在函数的作用域寻找变量i,没有找到,于是开始通过作用域链向上级作用域寻找,把全局总用域中的i=5付给i ;

补充

实际上变量名仅仅是一个标识符,js通过它获取对变量值的引用;

// for循环的正常执行状况,可与上面两种情况进行比较理解

for(var i=0;i<5;i++){
    console.log(i)
    }   
    //每次for循环都会执行console.log(i)函数,实际上log()函数也形成闭包了

划重点

导致上面两种for循环取值问题的原因,和闭包没有任何关系,真正的原因是for循环改变了自己所在作用域里面的i变量,而函数里面没有i且对for循环作用域里面的变量i的使用是在这个改变之后的

为什么闭包被用来背黑锅

闭包太常见了,有函数的地方几乎都会有闭包 ,激发条件是函数里面有一个存在于上级作用域的变量;


什么是闭包

闭包,javaScript里面神奇的存在,;在《你不知到的javaScript上卷》中称"理解闭包可以看作某种意义上的重生";但我认为真正难的并不是闭包本身而是人们对闭包的恐惧,是对预解释和js作用域的缺乏了解;是对javaScript语言本身特性理解的缺乏而把一些当前无法理解的问题盲目的踢给闭包,用闭包这个更大的不理解来安慰眼前的不理解。

从定义上来看,所有的函数都可以是闭包。当一个函数在调用时,引用了不是自己作用域内定义的变量(通常称其为自由变量),就形成了闭包;

闭包为什么难?

  1. 闭包本身涉及知识点较多,
  2. 各种书籍各成一派,缺乏同一标准;
  3. 一些博客错把闭包引起的问题说成闭包,对js新人产生很大的误导;

如何掌握闭包

  1. 牢记上述对闭包的定义,在学习过程中注意区分闭包概念和闭包产生的影响的不同
  2. 学习并彻底掌握js的作用域知识
  3. 要掌握js的作用域知识必须先掌握js预解析的知识

附:
js预解析总结

再次声明:自学Js中,还有很多知识点未掌握,本文无意冒犯任何人,不当之处欢迎扶正。

相关文章

  • 求你了,别再黑闭包了

    求你了,别再黑闭包了 声明:此文无意冒犯任何人,仅为个人学习总结,不适之处欢迎斧正。 引子 先看三段被称为js闭包...

  • 《求你别再熬夜了》

    高中时代最缺的就是睡觉的时间,睡觉的时间都是靠挤出来的,而大学的时间都是拿来熬夜煲电视剧,开黑的,一步入大学...

  • 求你了,别再啰嗦了

    我讨厌啰嗦的人,喋喋不休,反复咀嚼着一个意思重复说来说去。简直就是在碾轧听众的智商,摧残听者的耳膜。 有人说从心理...

  • 求你了,别再瞧不起自己了

    如果以生病作为我生活的一个结点。 我想是因为生病带我进入了一种新的生活,因为生病让我接触了那些美好的未知世界。 生...

  • 老公,求你别再爱我了

    老公,求你别再爱我了。 我承认,当初和老公在一起的时候我很爱他,他也很爱我。一直到现在他还是很爱我。只不过,我对他...

  • 求求你别再熬夜了!

    “回家泡个热水澡,睡个好觉,明天早晨起来满街都是男人,个个都比豹哥好。” 电影《甜蜜蜜》里的这句台词,把睡个好觉当...

  • 求你,别再做慈善了

    一 我迷了路。 在村里边转了好半天,也没找到那所学校。 这边住户少,交通不便,跟外界接触也少。年纪大点的人又不太会...

  • 我求你,别再花痴了。

    1 就像你看到的一样,我刚结束了我的第二段暗恋。 我是一个南方女生,慢热又迟钝,还是一个资深外貌协会成员。从初中开...

  • 求求你别再骂我了

    很多年前,我认识了王女士。 我们的初见始于一次帮助。 那年我小学毕业,闲来无事报了个素描班。结束那天我的书包里塞满...

  • 求你别再发怒了!

    每次遇到不顺心的事情,我只会通过愤怒去表达自己的感受 比如被阶梯绊了一下,我竟然会恶狠狠的踢它,觉得它绊我是不对的...

网友评论

      本文标题:求你了,别再黑闭包了

      本文链接:https://www.haomeiwen.com/subject/uaommxtx.html