• 练习题-----可以很好地诠释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();    
  • 相关阅读:
    20190318-使用类做一个简单的图书馆管理系统
    20190313-面向对象的简单理解
    20190313-时间和日期-Time
    20190305-leetcode题目有效的括号
    20190227-做一个简易代码统计工具
    20190226-利用序列化完成小型记账程序
    20190221-文件操作
    20190131-文件操作命题练习
    Excel技巧—如何从重复行中取某一行
    Excel技巧—轻松搞定多级联动下拉列表
  • 原文地址:https://www.cnblogs.com/heisetianshi/p/13937790.html
Copyright © 2020-2023  润新知