JavaScript for 循环闭包陷阱:为什么会打印 3

副标题 / 摘要 for 循环里的闭包经常会打印同一个值。本文解释原因,并给出可运行修复方法。 目标读者 使用 JavaScript 的开发者 需要理解闭包的工程师 前端与全栈团队 背景 / 动机 JavaScript 的函数作用域与闭包容易导致“循环变量捕获”问题。 理解这个陷阱能避免常见 Bug。 核心概念 闭包:函数捕获外部变量 作用域:var 与 let 的区别 事件回调:延迟执行时才读取变量 实践指南 / 步骤 用 let 替代 var 或使用立即执行函数(IIFE) 把循环变量变成函数参数 在回调中避免直接引用 var 变量 可运行示例 <button id="button0">0</button> <button id="button1">1</button> <button id="button2">2</button> <script> function hookupevents() { for (let i = 0; i < 3; i++) { document.getElementById("button" + i) .addEventListener("click", function() { alert(i); }); } } hookupevents(); </script> 解释与原理 使用 var 时,循环结束后 i 的值为 3,闭包读取的是同一个变量。 用 let 会创建块级作用域,每次循环都有独立 i。 ...

2026年1月24日 · 1 分钟 · map[name:Jeanphilo]

为什么 SQL 中 NULL 不能用 = 比较:三值逻辑与查询陷阱

副标题 / 摘要 在 SQL 中,NULL 代表“未知”,因此 = 比较不会返回 true。本文解释三值逻辑的机制,并给出正确写法。 目标读者 经常写 SQL 的后端工程师 在查询结果上踩过 NULL 坑的开发者 需要制定查询规范的团队 背景 / 动机 很多人会写: SELECT * FROM t WHERE field = NULL; 然后发现它“不起作用”。原因是 SQL 使用三值逻辑,NULL 不等于任何值(包括 NULL 本身)。 核心概念 NULL 表示未知,不是空字符串或 0 三值逻辑:true / false / unknown 正确判断方式:IS NULL / IS NOT NULL 实践指南 / 步骤 判断 NULL 用 IS NULL 不要用 = 与 NULL 比较 需要替代值时用 COALESCE 对外部输入做明确转换 可运行示例 SELECT id FROM users WHERE deleted_at IS NULL; 使用替代值: SELECT COALESCE(age, 0) FROM users; 解释与原理 NULL = NULL 的结果是 unknown,而不是 true。 SQL 的 WHERE 只保留 true 的行,unknown 会被过滤掉,因此查询为空。 ...

2026年1月24日 · 1 分钟 · map[name:Jeanphilo]