」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > ⚠️ 在 JavaScript 中使用 `var` 的隱藏危險:為什麼是時候繼續前進了

⚠️ 在 JavaScript 中使用 `var` 的隱藏危險:為什麼是時候繼續前進了

發佈於2024-11-07
瀏覽:743

⚠️ 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]刪除
最新教學 更多>
  • 使用Wildcard Imports對不對?
    使用Wildcard Imports對不對?
    避免通配符導入的情況合格的名稱優於Barenames。最好使用PYQT4.QTCORE IMPICT QT而不是從PYQT4 Import QT中明確指定您要導入的模塊。合格的名稱使跟踪代碼依賴性和調試錯誤變得更容易。 他們還降低了模塊之間碰撞的風險。如果兩個模塊定義了具有相同名稱的函數,則需要明確...
    程式設計 發佈於2025-04-17
  • Vitest、MSW與Playwright在React+Vite+TS項目中的配置 - 第三部分
    Vitest、MSW與Playwright在React+Vite+TS項目中的配置 - 第三部分
    1。安裝劇作家 要設置playwright,運行以下命令: NPM初始化劇作@最新 npm init playwright@latest 您將通過終端中的設置嚮導引導。當提示使用“將端到端測試放在哪裡?” ,您可以將其設置為src/tests(如較早的教程中的建議)。 [2 ...
    程式設計 發佈於2025-04-17
  • 如何用單一SQL查詢獲取varchar字段的大小?
    如何用單一SQL查詢獲取varchar字段的大小?
    在SQL中檢索varchar [n]字段的大小,並使用一個查詢確定VARCHAR字段的長度對於數據管理和存儲優化。在SQL中,您可以執行單個語句來檢索此信息。 syntax:說明: 字段的名稱。 data_type:這將提供該列的數據類型,該列應該為'varchar'。 。 ...
    程式設計 發佈於2025-04-17
  • Python不會對超範圍子串切片報錯的原因
    Python不會對超範圍子串切片報錯的原因
    在python中用索引切片範圍:二重性和空序列索引單個元素不同,該元素會引起錯誤,切片在序列的邊界之外沒有。 這種行為源於索引和切片之間的基本差異。索引一個序列,例如“示例” [3],返回一個項目。但是,切片序列(例如“示例” [3:4])返回項目的子序列。 索引不存在的元素時,例如“示例” [9...
    程式設計 發佈於2025-04-17
  • 如何實時捕獲和流媒體以進行聊天機器人命令執行?
    如何實時捕獲和流媒體以進行聊天機器人命令執行?
    在開發能夠執行命令的chatbots的領域中,實時從命令執行實時捕獲Stdout,一個常見的需求是能夠檢索和顯示標準輸出(stdout)在cath cath cant cant cant cant cant cant cant cant interfaces in Chate cant inter...
    程式設計 發佈於2025-04-17
  • 為什麼使用固定定位時,為什麼具有100%網格板柱的網格超越身體?
    為什麼使用固定定位時,為什麼具有100%網格板柱的網格超越身體?
    網格超過身體,用100%grid-template-columns 為什麼在grid-template-colms中具有100%的顯示器,當位置設置為設置的位置時,grid-template-colly修復了? 問題: 考慮以下CSS和html: class =“ snippet-code”> ...
    程式設計 發佈於2025-04-17
  • 如何簡化PHP中的JSON解析以獲取多維陣列?
    如何簡化PHP中的JSON解析以獲取多維陣列?
    php 試圖在PHP中解析JSON數據的JSON可能具有挑戰性,尤其是在處理多維數組時。 To simplify the process, it's recommended to parse the JSON as an array rather than an object.To do...
    程式設計 發佈於2025-04-17
  • 無管理C++客戶端如何與WCF服務通信?
    無管理C++客戶端如何與WCF服務通信?
    在不管理的C客戶端與WCF服務之間的差距可以通過在託管c中寫入橋樑DLL來與WCF服務無縫地通信。這是建立此連接的綜合指南: 1。創建端點接口和類:定義了wcf Service的C#接口(ihelloservice)及其相應的實現類(HelloService)。創建Windows NT服務:創建一...
    程式設計 發佈於2025-04-17
  • Java中Lambda表達式為何需要“final”或“有效final”變量?
    Java中Lambda表達式為何需要“final”或“有效final”變量?
    Lambda Expressions Require "Final" or "Effectively Final" VariablesThe error message "Variable used in lambda expression shou...
    程式設計 發佈於2025-04-17
  • 可以在純CS中將多個粘性元素彼此堆疊在一起嗎?
    可以在純CS中將多個粘性元素彼此堆疊在一起嗎?
    [2这里: https://webthemez.com/demo/sticky-multi-header-scroll/index.html </main> <section> { display:grid; grid-template-...
    程式設計 發佈於2025-04-17
  • 選哪個Java HTML解析器適合我的項目?
    選哪個Java HTML解析器適合我的項目?
    領導Java HTML Parsers:優勢和弱點在Java EcoSystem中,選擇正確的HTML Parser對於各種Web Automation Tasks可能是至關重要的。一些推薦的解析器包括Jtidy,Nekohtml,Jsoup和Tagsoup。每個都提供獨特的功能和缺點。 常規特徵...
    程式設計 發佈於2025-04-17
  • 如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    如何從PHP中的Unicode字符串中有效地產生對URL友好的sl。
    為有效的slug生成首先,該函數用指定的分隔符替換所有非字母或數字字符。此步驟可確保slug遵守URL慣例。隨後,它採用ICONV函數將文本簡化為us-ascii兼容格式,從而允許更廣泛的字符集合兼容性。 接下來,該函數使用正則表達式刪除了不需要的字符,例如特殊字符和空格。此步驟可確保slug僅包...
    程式設計 發佈於2025-04-17
  • 您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    您可以使用CSS在Chrome和Firefox中染色控制台輸出嗎?
    在javascript console 中顯示顏色是可以使用chrome的控制台顯示彩色文本,例如紅色的redors,for for for for錯誤消息? 回答是的,可以使用CSS將顏色添加到Chrome和Firefox中的控制台顯示的消息(版本31或更高版本)中。要實現這一目標,請使用以下...
    程式設計 發佈於2025-04-17
  • 使用Spring Boot和LangChain探索JLama圖書館
    使用Spring Boot和LangChain探索JLama圖書館
    [2 大語言模型(LLMS)正在改變包括軟件開發在內的各種字段。 他們理解和生成文本(和其他數據類型)的能力可以從文本提示中實現代碼建議,更正甚至生成。本文探討了 jlama 庫,這是一種基於Java的解決方案,用於將LLMS集成到Java生態系統中。 Jlama提供了靈活性,可作為命令行接口(...
    程式設計 發佈於2025-04-17
  • 在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    在Ubuntu/linux上安裝mysql-python時,如何修復\“ mysql_config \”錯誤?
    mysql-python安裝錯誤:“ mysql_config找不到”“ 由於缺少MySQL開發庫而出現此錯誤。解決此問題,建議在Ubuntu上使用該分發的存儲庫。使用以下命令安裝Python-MysqldB: sudo apt-get安裝python-mysqldb
    程式設計 發佈於2025-04-17

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3