zoukankan      html  css  js  c++  java
  • 练习题-----可以很好地诠释js的运行机制

    先看一下题:

    现有如下html结构

    1 <ul>
    2       <li></li>
    3       <li></li>
    4       <li></li>
    5       <li></li>
    6 </ul>

    运行如下代码:

    1 var elements = document.getElementsByTagName('li');
    2 var length = elements.length;
    3 for(var i=0;i<length;i++) {
    4     elements[i].onclick = function() {
    5          console.log(i)
    6     }
    7 }

    依次点击四个li标签,下列选项哪个正确?

    A、1234        B、0123       C、3333      D、4444

    这个是选择D的,以下是解释:

    这里考的是JS的运行机制! 事件(click,focus等等),定时器(setTimeout和setInterval),ajax,都会触发异步,属于异步任务;而js是单线程的,一个时间点只能做一件事,所以优先处理同步任务,按照代码从上往下执行,遇到异步,就挂起,放到异步任务里,继续执行同步任务,只有同步任务执行完了,才去看看有没有异步任务,然后再按照顺序执行! 这里for循环是同步任务,onclick是异步任务,所以等for循环执行完了,此时i变成4,注意:这里因为i是全局变量,最后一个i++,使得i为4(后面的onclick函数,最后在循环外面执行,不受i<length限制); 所以for循环每执行一次,onclick事件函数都会被挂起一次,共4次; for循环结束后,点击事件 触发了4个onclick函数,接着输出4个4!

    有以下几个解决方法:(输出结果都是   0  1   2   3)

    1、利用块级作用域

    1 var elements = document.getElementsByTagName('li');
    2 var length = elements.length;
    3 for(let i=0;i<length;i++) {
    4     elements[i].onclick = function() {
    5                 console.log(i)
    6     }
    7 }    

    2、利用自执行函数,将i作为参数传入

    1 var elements = document.getElementsByTagName('li');
    2 var length = elements.length;
    3 for(var i=0;i<length;i++) {
    4     (function(i) {
    5      elements[i].onclick = function() {
            console.log(i)
    6        }
    7    })(i) 
    8 }

    3、利用promise

     1 var elements = document.getElementsByTagName('li');
     2 var length = elements.length;
     3 for(var i=0;i<length;i++) { 
     4      new Promise((resolve,reject)=> {
     5             var j=i;
     6             elements[j].onclick = function() {
     7                 console.log(j)      
     8             }
     9      }) 
    10 }

    4、利用async函数

     1 var elements = document.getElementsByTagName('li');
     2 var length = elements.length;
     3 async function foo() {
     4     for(var i=0;i<length;i++) {
     5         let result = await new
     6         Promise((resolve,reject)=>{
     7             elements[i].onclick = function() {
     8                  resolve(i)     
     9            }
    10         });
    11         console.log(result)
    12     }
    13 }
    14 foo();    
  • 相关阅读:
    牛客 158F 青蛙 (贪心)
    牛客 158D a-贝利福斯数
    长沙理工大学第十二届ACM大赛-重现赛 大家一起来数二叉树吧 (组合计数)
    美团2017年CodeM大赛-初赛B轮 黑白树 (树形dp)
    美团2017年CodeM大赛-初赛A轮 C合并回文子串
    活动安排问题
    0和5
    1489 蜥蜴和地下室
    1067 Bash游戏 V2
    1062 序列中最大的数
  • 原文地址:https://www.cnblogs.com/heisetianshi/p/13937790.html
Copyright © 2011-2022 走看看