”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > ⚠️ 在 JavaScript 中使用 `var` 的隐藏危险:为什么是时候继续前进了

⚠️ 在 JavaScript 中使用 `var` 的隐藏危险:为什么是时候继续前进了

发布于2024-11-07
浏览:930

⚠️ The Hidden Dangers of Using `var` in JavaScript: Why It’s Time to Move On

关键字 var 多年来一直是 JavaScript 中声明变量的默认方式。但是,它有一些怪癖和陷阱,可能会导致代码出现意外行为。现代替代方案(如 let 和 const)解决了许多此类问题,使它们成为大多数情况下声明变量的首选。


1️⃣ 提升:var 在不知不觉中声明变量!

?解释:

在 JavaScript 中,var 声明被提升到其作用域的顶部,这意味着即使声明稍后出现在代码中,它们也会被初始化为未定义。这可能会导致令人困惑的行为并导致难以检测的错误。

?要点:

  • 提升操作:变量声明被移动到作用域的顶部,但它们的赋值却没有。
  • 意外的未定义值: 变量可以在赋值之前使用,从而导致意外的未定义结果。

?例子:

console.log(myVar);  // undefined (hoisted but not initialized)
var myVar = 10;
console.log(myVar);  // 10

?注释: 变量 myVar 被提升到作用域的顶部,但最初是未定义的,这可能会导致代码混乱。

?使固定:

  • 使用let或const:这些关键字的提升方式与var不同,这有助于防止此问题。

?修复示例:

console.log(myLet);  // ReferenceError: myLet is not defined
let myLet = 10;
console.log(myLet);  // 10

?注释: 使用 let 可以防止变量在声明之前被访问,从而减少混乱和潜在的错误。


2️⃣ 函数作用域与块作用域:var 可以泄漏出块!

?解释:

var 的主要缺陷之一是它是函数作用域,而不是块作用域。这意味着在循环、if 语句或其他块内声明的变量不限于该块,而是可以在其外部访问,这可能会导致错误。

?要点:

  • 函数作用域: var 的作用域为最近的函数,即使在循环或 if 语句等块内声明也是如此。
  • 泄漏变量:这可能会导致变量无意中泄漏出块,从而导致不可预测的行为。

?例子:

if (true) {
  var blockVar = "I’m accessible outside this block";
}
console.log(blockVar);  // "I’m accessible outside this block"

?注释: 虽然 blockVar 是在 if 块内声明的,但它仍然可以在块外访问,因为 var 是函数作用域,而不是块作用域。

?使固定:

  • 使用let或const:这些关键字是块作用域的,这意味着它们只能在定义它们的块内访问。

?修复示例:

if (true) {
  let blockLet = "I’m only accessible inside this block";
}
console.log(blockLet);  // ReferenceError: blockLet is not defined

?注释: 使用 let 或 const 可确保变量保持在各自的块内,防止作用域泄漏。


3️⃣ 重新声明问题:var 让您可以声明相同的变量两次!

?解释:

使用 var,您可能会意外地在同一作用域中重新声明同一变量,这可能会覆盖以前的值。这可能会导致无意的错误,尤其是在较大的代码库中,变量名称可能会被错误地重用。

?要点:

  • 重新声明变量: var 允许您在同一范围内重新声明变量,可能会覆盖现有值。
  • 意外覆盖:这可能会导致难以检测的错误,尤其是在大型或复杂的函数中。

?例子:

var name = "Alice";
var name = "Bob";  // No error, overwrites the previous value
console.log(name);  // "Bob"

?注释: 第二个名称声明会覆盖第一个名称,可能会导致代码中的错误。

?使固定:

  • 使用let或const:这些关键字可以防止您在同一范围内重新声明变量,从而降低意外覆盖的风险。

?修复示例:

let name = "Alice";
let name = "Bob";  // SyntaxError: Identifier 'name' has already been declared

?评论: 使用 let 或 const 可以帮助您避免重新声明变量并确保您的代码保持可预测性。


4️⃣ 循环中的 var:异步代码中潜在的错误

?解释:

在循环中使用 var 时,变量的值可能会以意想不到的方式更改,尤其是在使用异步代码时。由于 var 是函数作用域而不是块作用域,因此在异步回调内部访问时,循环变量可能会包含意外值。

?要点:

  • 循环变量:循环内用 var 声明的变量不限于循环块,导致稍后访问时可能出现错误。
  • 异步问题: 这可能会导致 setTimeout 或 Promise 等异步操作中出现错误,其中循环变量可能具有意外值。

?例子:

for (var i = 0; i  console.log(i), 1000);  // Prints: 3, 3, 3 (unexpected)
}

?注释: 因为 var 不是块作用域,所以循环变量 i 在所有迭代中共享,并且其最终值 (3) 在每个 setTimeout 回调中使用。

?使固定:

  • 使用let: let关键字是块作用域的,确保循环的每次迭代都获得自己独立的循环变量值。

?修复示例:

for (let i = 0; i  console.log(i), 1000);  // Prints: 0, 1, 2 (as expected)
}

?评论: 使用 let 为每次迭代创建一个新的 i 实例,修复异步回调问题并确保打印正确的值。


5️⃣ var 和闭包:混乱的根源

?解释:

闭包与 var 结合使用时可能会导致意外行为。由于 var 是函数作用域的,因此当闭包捕获它时,它的值可能会以意想不到的方式发生变化。

?要点:

  • JavaScript 中的闭包: 闭包是一种即使在外部函数执行完毕后仍能记住其周围作用域的函数。
  • 共享变量问题:当 var 在闭包内使用时,捕获的变量可能会在所有闭包之间共享,从而导致意外行为。

?例子:

function createFunctions() {
  var funcs = [];
  for (var i = 0; i 



?评论: 所有闭包都捕获相同的 i 值,因为 var 是函数范围的,导致意外结果。

?使固定:

  • 使用let:通过使用let,每个闭包捕获循环变量的一个新实例,解决了问题。

?修复示例:

function createFunctions() {
  var funcs = [];
  for (let i = 0; i 



?评论: 使用 let,每个闭包都会获得自己的 i 副本,解决问题并确保打印预期值。


?结论:是时候告别 var

虽然 var 是 JavaScript 中声明变量的原始方式,但它有几个缺点,使其成为现代 JavaScript 开发中的糟糕选择。 let 和 const 的引入提供了更好的作用域,降低了错误风险,并使代码更具可预测性。为了编写更干净、更易于维护的 JavaScript,是时候从 var 转向使用 let 和 const。

版本声明 本文转载于:https://dev.to/dharamgfx/the-hidden-dangers-of-using-var-in-javascript-why-its-time-to-move-on-2jgm?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 为什么sync.Once使用atomic.StoreUint32而不是标准分配?
    为什么sync.Once使用atomic.StoreUint32而不是标准分配?
    sync.Once中的原子内存排序在探索sync.Once的源代码时,我们偶然发现了使用atomic背后的原因。 StoreUint32 而不是像 o.done = 1 这样的标准赋值。Go 中的内存排序并发编程中的一个基本概念是内存排序,它确保共享内存在所有处理器上一致地观察到访问。然而,不同的架...
    编程 发布于2024-11-07
  • 为什么无法在 PHP 中使用匿名函数初始化属性?
    为什么无法在 PHP 中使用匿名函数初始化属性?
    使用匿名函数初始化属性:为什么以及如何?如下面的代码片段中所述,在类声明在 PHP 中触发“解析错误:语法错误,意外的 T_FUNCTION”。然而,在构造函数中将函数分配给属性是可能的,如第二个片段所示。// Property initialization with anonymous funct...
    编程 发布于2024-11-07
  • [Flatiron SE] 第 24 天
    [Flatiron SE] 第 24 天
    大家好,在这里吃饭, 这将是我的第一篇博客文章!我是应熨斗学校出色的老师的要求这样做的。我将尝试每天发表一篇博客文章,记录我在编码过程中的发展。您好,欢迎,以及将来阅读本文的雇主! 现在我需要说实话,这实际上并不是我使用熨斗的“第一天”。我实际上是在两天前的星期一开始的。但我相信今天绝对是我真正投入...
    编程 发布于2024-11-07
  • 保护 JavaScript 应用程序的安全:常见漏洞以及如何避免它们
    保护 JavaScript 应用程序的安全:常见漏洞以及如何避免它们
    JavaScript 是最流行的 Web 开发语言之一,但由于其广泛使用,它也是攻击者的常见目标。保护 JavaScript 应用程序的安全对于避免可能导致数据被盗、用户帐户受损等安全漏洞至关重要。本文将探讨 JavaScript 应用程序中的一些常见漏洞并提供缓解这些漏洞的策略。 ...
    编程 发布于2024-11-07
  • 如何从 Flask 中的 URL 中提取命名参数?
    如何从 Flask 中的 URL 中提取命名参数?
    从 Flask 中的 URL 中提取命名参数假设您有一个类似 http://10.1.1.1:5000/login?username 的 URL =alex&password=pw1 您希望 Flask 应用程序处理。要访问问号后指定的参数,请使用 request.args,而不是 request....
    编程 发布于2024-11-07
  • 一级抽象:简洁函数的关键
    一级抽象:简洁函数的关键
    曾经在看过一个函数后,感到迷失在它的复杂性中吗?让我们探讨一下干净代码的基本原则:函数应该只维护一个抽象级别。 这是在 Web 应用程序中创建用户的真实示例: // ❌ A function doing too many things at different abstraction levels ...
    编程 发布于2024-11-07
  • 在 JavaScript 中编写简洁且可维护的代码的最佳实践
    在 JavaScript 中编写简洁且可维护的代码的最佳实践
    干净且可维护的代码对于任何软件项目的长期成功和可扩展性至关重要。它改善了团队成员之间的协作,减少了错误的可能性,并使代码更易于理解、测试和维护。在这篇博文中,我们将探讨一些在 JavaScript 中编写干净且可维护的代码的最佳实践,以及说明每种实践的代码示例。 1. 一致的代码格式...
    编程 发布于2024-11-07
  • 促进软件开发成功:整合跨学科技能以获得更好的结果
    促进软件开发成功:整合跨学科技能以获得更好的结果
    In today's world of software development, success is more than just technical know-how. Teams that work well together and mix different skills in vari...
    编程 发布于2024-11-07
  • WatchYourLAN - 轻量级网络 IP 扫描器
    WatchYourLAN - 轻量级网络 IP 扫描器
    WatchYourLAN的主要特点 找到新主机时发送通知 监控主机在线/离线历史记录 保留网络中所有主机的列表 发送数据到InfluxDB2制作Grafana仪表板 v2 有什么新功能? 基础API 导出到 InfluxDB2 SQLite 和 PostgreSQL...
    编程 发布于2024-11-07
  • 掌握 React Native 中的深度链接和通用链接:OpenGraph Share 和 Node.js 集成
    掌握 React Native 中的深度链接和通用链接:OpenGraph Share 和 Node.js 集成
    设想 假设您有一个名为 ShopEasy 的电子商务应用程序,并且您希望点击电子邮件、消息或社交媒体中的产品链接的用户被直接重定向到应用程序中的相关产品页面,而不是网站。 步骤1:在nodejs服务器中进行Opengraph配置以进行链接预览: Open Graph...
    编程 发布于2024-11-07
  • 如何在不使用“eval”的情况下安全地解析“宽松”JSON?
    如何在不使用“eval”的情况下安全地解析“宽松”JSON?
    在没有风险评估的情况下解析“轻松”的 JSONJSON 是一种广泛使用的数据交换格式,需要带引号的键的严格语法。但是,某些应用程序可能会遇到带有不带引号的键的“宽松”JSON。由于安全风险,不鼓励使用 eval 解析此类数据。避免邪恶的 Evaleval 的一种替代方法是基于正则表达式的方法,该方法...
    编程 发布于2024-11-07
  • 通过sponge+dtm快速轻松实现高性能的电商系统
    通过sponge+dtm快速轻松实现高性能的电商系统
    This article demonstrates how to use the Sponge framework to quickly build a simplified high-performance e-commerce system, implementing flash sale an...
    编程 发布于2024-11-07
  • 什么是 Java 中的关闭钩子以及如何有效地使用它?
    什么是 Java 中的关闭钩子以及如何有效地使用它?
    1. 了解关闭钩子 关闭钩子是 Java 中的一种特殊构造,允许您注册一个线程,该线程将在 Java 虚拟机 (JVM) 关闭时执行。这可以由各种事件触发,例如用户中断 (Ctrl C)、系统关闭或编程终止。 1.1 关闭钩子如何工作 当 JVM 启动时,它会创建...
    编程 发布于2024-11-07
  • 在 Web 工具中使用 JavaScript 进行安全加密
    在 Web 工具中使用 JavaScript 进行安全加密
    这是开发人员用来帮助保护程序中的敏感信息免受潜在攻击者攻击的方法。加密将可读数据转变为编码格式,只有使用正确的密钥才能解码;因此,它对于保护密码、财务详细信息和个人数据等信息的安全至关重要。 在数据泄露和网络攻击非常猖獗的时候,这一点变得非常重要。通过加密数据,开发人员将确保没有未经授权的一方在网络...
    编程 发布于2024-11-07
  • 如何将 java.util.Date 转换为 java.time 类型?
    如何将 java.util.Date 转换为 java.time 类型?
    将 java.util.Date 转换为 java.time 类型遗留的 java.util.Date 和 Calendar 类以其复杂性而闻名和麻烦。虽然建议使用 java.time 框架进行日期时间管理,但在使用现有代码时,必须在这些新旧类型之间进行转换。映射到 java.time 类型将 ja...
    编程 发布于2024-11-07

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3