首页 > 编程语言 >[编程笔记] JavaScript作用域问题

[编程笔记] JavaScript作用域问题

时间:2024-12-03 11:21:25浏览次数:4  
标签:逻辑 编程 作用域 代码 JavaScript ++ 事件 var

    很有意思的一个bug,起初看到同事对一段代码的批注:

    批注地方的代码(也就是for里面的i),在实际触发时,返回是是7,而理想情况下我们希望点击哪个datagrid就返回哪个i,实际则是每次都是7,也就是for结束后的结果,6,i++,所以是7。

    那么为什么会这样呢?

    抱着好奇的心态我用一个简单的demo复现了该问题:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="./jquery-1.8.3.min.js"></script>
    </head>
    <body>
        <input type="button" value="按钮1" id="btn1">
        <input type="button" value="按钮2" id="btn2">
        <input type="button" value="按钮3" id="btn3">
    </body>

</html>
<script>
    $(function () {
        for (var i = 1; i <= 3; i++) {
             $("#btn" +i).on("click",function(){ 
                alert("触发点击事件!" + i);
             })
        }
    })
</script>

    研究一二之后知道了原因:

    1、for是同步的,但事件是异步的,所以代码跑完了,这个时候注册事件,i就是最新的值了

    2、var作用域是全局的,由于没有限制作用域,每次注册事件访问的都是同一个i

    这里的注册事件我的理解分为两步,一步是声明事件,即我要注册这个dom的事件了,哪个呢,就是"#btn" +i ,另一个步则是实现事件逻辑,即我要怎么做了。

    因此在声明的时候,代码是同步逻辑,可以取到当前的i,但是实现事件逻辑的时候,由于是异步的,for已经走完了才开始走事件的实现逻辑,同时由于使用的var进行定义变量,那么全局到处可读,这个时候i就是i++后的值了。

    知道原因后解决起来就很简单,控制下i的作用域,var i 改成let i 就可以了,这是最简单最好用的写法,此时i已经是块级作用域,所以后续实现事件逻辑时,每个事件里的i就是各自的i了,i++不会再把其他事件里的i给累加。

    

    大致上就是这么一个过程。很简单的一个问题,但是也涵盖了一些知识点在里面。虽然同事当时未能找到原因,不过通过其他方法也解决了这个问题,他在外层定义了一个变量gridID,每次切换tabs时更新这个gridID,这样代码就OK了。

    方法有很多,知道是什么原因就好解决了。

 

    参考博客:https://blog.csdn.net/qq_42539194/article/details/113920185

标签:逻辑,编程,作用域,代码,JavaScript,++,事件,var
From: https://www.cnblogs.com/sunshine-wy/p/18583723

相关文章

  • 举例说明什么是响应式编程?
    响应式编程在前端开发中,指的是一种编程范式,它关注于数据流和变化的传播。当底层数据变化时,依赖于这些数据的组件或视图会自动更新。可以把它想象成Excel表格,当你修改一个单元格的值时,所有依赖于这个单元格的公式和图表都会自动重新计算和更新。以下是一些前端响应式编程的例......
  • 什么是函数式编程?它有什么优缺点?
    函数式编程是一种编程范式,它将计算视为数学函数的求值,避免状态变化和数据可变。它强调:纯函数:给定相同的输入,总是返回相同的输出,并且没有副作用(例如修改全局变量或进行I/O操作)。不可变数据:数据一旦创建就不能更改。要更新数据,需要创建一个新的数据副本,而不是修改原始数据。......
  • 买了系统编程花钱买罪受!
    总有一些企业在你意想不到的地方严格控制成本,比如在选择ERP系统的时候。结果呢?花了钱,只买到了一个功能简陋的ERP系统,最后还是离不开纸质单据。钱花了,工作量增加了,账目反而更乱了。这些企业似乎总是抱有一种幻想:既能快速提升效率,又能省钱,还能保证账目清晰。但是现实是,要么全面......
  • 实验五 C语言指针应用编程
    实验五C语言指针应用编程实验任务1——数组求最大最小值#include<stdio.h>#defineN5voidinput(intx[],intn);voidoutput(intx[],intn);voidfind_min_max(intx[],intn,int*pmin,int*pmax);intmain(){ inta[N]; intmin,max; printf("录入%d个数......
  • 实验5 C语言指针应用编程
    一,实验目的1,深度理解使用指针变量间接访问数据,代码2,会使用指针变量间接访问一维数组元素,二维数组元素3,会使用指针变量处理字符串4,会使用指针变量作为函数参数(形参,实参)和返回值5,能灵活应用数组,指针,函数,编程解决实际问题二,实验准备使用指针间接访问数组(一维,两维)指针作为函数......
  • JavaScript 事件循环与异步编程详解
    JavaScript事件循环与异步编程详解1.事件循环基础概念JavaScript是单线程语言,但通过事件循环(EventLoop)机制实现了异步操作。事件循环包含以下关键组件:调用栈(CallStack)任务队列(TaskQueue/CallbackQueue)微任务队列(MicrotaskQueue)WebAPIs(浏览器环境)1.1基本运行机......
  • JavaScript操作数组
    数组的遍历、插入、删除操作在JavaScript中,数组是一种常见的数据结构,可以包含多个元素,并且可以进行遍历、插入和删除等操作。下面分别介绍数组的遍历、插入和删除操作。1,数组的判断:代码不能操作空对象(空指针),在操作数组之前,一般建议先判断数组是否为空。letarr=[1,2,3];/......
  • JavaScript操作addEventListener监听触发事件
    JavaScript的addEventListener方法允许你为指定的HTML元素添加事件监听器。以下是一些常见的事件类型,可以使用addEventListener来监听它们:1,点击事件(click)点击事件(click):当用户点击元素时触发。element.addEventListener('click',function(){console.log......
  • JavaScript操作DOM元素的classList
    在JavaScript中,classList是一个DOM元素属性,它提供了一组方法来添加、移除和切换元素的类名。classList属性返回一个DOMTokenList集合,表示元素的类名。这个集合提供了几个非常有用的方法,我们可以方便地对元素的类名进行操作,包括添加、移除、切换类名等。1,添加类名add(class1......
  • Linux C/C++编程之静态库
    【图书推荐】《LinuxC与C++一线开发实践(第2版)》_linuxc与c++一线开发实践pdf-CSDN博客《LinuxC与C++一线开发实践(第2版)(Linux技术丛书)》(朱文伟,李建英)【摘要书评试读】-京东图书(jd.com)10.3.1 静态库的基本概念静态库文件的后缀为.a,在Linux下一般命名为libxxx.a。当......