这作用域的问题还是没搞清楚

这作用域的问题还是没搞清楚

为什么

    var btns = document.getElementsByTagName('button');

         for (var i = 0; i < 3; i++) {

           click(i);

   }

   

   function click(i){

       btns[i].onclick = function () {

    alert(i + 1);

    };

   }

这样就每个按钮对应一个i呢?

像之前的就都循环完毕后,每个按钮对应的都是4呢?这个该怎么分析呢?

正在回答

登陆购买课程后可参与讨论,去登陆

1回答

因为JS是单线程的,代码一行行执行,如果遇到一行定时器的代码,那就会影响后面的代码执行,会卡在那里等定时器的执行完再执行下面的代码。为了解决这个问题就有了同步任务和异步任务,比如点击事件,定时器这些是异步任务。

JS会先把同步任务先执行完,再去执行异步任务,for循环就是同步任务,所以一开始就执行完了,循环完等你触发点击事件之后,才会把它从异步任务送到执行栈中执行。

所以需要闭包把每次循环的i都存起来http://img1.sycdn.imooc.com//climg/5ef5dfb009c3ff2810030565.jpg

  • 慕婉清6507108 提问者 #1
    我这里没有用到定时器呀,你是不是回答错地方了?
    2020-06-26 20:10:15
  • 慕标1234374 回复 提问者 慕婉清6507108 #2
    没有,定时器,还有点击事件这种类型的都是异步任务,因为点击事件是需要用户点击了之后才会触发这个事件,所以它没办法参加到for循环里面,取不到每次循环i的值,等到用户点击之后才触发这个事件,这个时候for循环老早就执行完毕了,i=3,所以绑定事件里面的btns[i]都是3,alert(i + 1)出来的值都是4
    2020-06-26 22:03:15
  • 慕标1234374 回复 提问者 慕婉清6507108 #3
    你可以简单理解为,js是一行行执行下去的,如果碰到了一行点击事件的代码,用户不点击,就永远触发不了这个事件,这行点击事件的代码就会卡住,后面的代码就执行不了。所以JS会将这种事件放到异步进程中等待,把那种不用等待的先全部执行了(for循环就是这个时候执行完毕了,最后i的值是3),然后当用户点击之后,才会把这个异步任务拿过来执行。
    2020-06-26 22:07:10
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
2.组件化网页开发
  • 参与学习           人
  • 提交作业       1121    份
  • 解答问题       14456    个

本阶段在运用JS实现动态网页开发的基础上,带你深入理解企业开发核心思想,完成一个企业级网页的开发,体验前端工程师的成就感。

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师