“Uncaught ReferenceError”——你的第一个敌人?学会正确检查JavaScript中的undefined
\n\n每个写过几行JavaScript代码的人,都遇到过神秘的undefined。它不仅仅是“空位”——它是一个拥有自身值的完整数据类型。但如何正确地捕获它呢?如果你曾搜索过“How can I check for undefined in JavaScript”,你并不孤单:这个问题在Stack Overflow上获得了数十万次浏览。问题在于,JS中有多种检查方法,每种方法都暗藏陷阱。
在本文中,我们将从简单到复杂,逐一剖析5种方法,比较它们的性能和可靠性,并找出在2025年应该使用哪种方法。开始吧!
\n\nundefined到底是什么?
\n\n在开始检查之前,让我们先统一术语。undefined是一个原始值,当变量被声明但未初始化时,它会被赋值给该变量:
let a;\nconsole.log(a); // undefined\n\n\n重要提示:undefined ≠ null ≠ not defined。null是有意设置的“空值”,而not defined(ReferenceError)则表示变量根本未被声明。这些细微差别对于选择正确的检查方法至关重要。
方法1:typeof运算符——黄金标准?
\n\n最流行且最安全的方法是使用typeof:
if (typeof x === 'undefined') {\n console.log('x未定义');\n}\n\n\n为什么它甚至对未声明的变量也有效? typeof永远不会抛出ReferenceError。如果变量不存在,它只会返回字符串"undefined"。
优点:
\n- \n
- 对未声明的变量安全 \n
- 代码可读性强,易于理解 \n
- 在所有浏览器和环境中都有效(Node.js, Deno) \n
缺点:
\n- \n
- 频繁使用时略显冗长 \n
- 可能会误导新手(字符串比较) \n
结论:全局检查和变量可能未声明时的最佳选择。
\n\n方法2:与undefined严格比较(===)
\n\n第二种流行的方法是直接比较值:
\n\nif (x === undefined) {\n console.log('x等于undefined');\n}\n\n\n这里有一个细微之处:变量必须已被声明。如果x不存在,你会收到ReferenceError。因此,这种代码仅对以下情况安全:
\n- \n
- 对象的属性(
obj.prop === undefined) \n - 函数的参数 \n
- 通过
let、const或var声明的变量 \n
陷阱:全局undefined
\n在旧版浏览器中(IE 8及以下),undefined可以被覆盖:
undefined = '现在我是一个字符串'; // 噩梦!\n\n现在这已不可能(在严格模式下),但如果你需要支持遗留代码,最好使用typeof。
结论:对于局部变量和对象属性来说,这是一个极好的方法。快速且简洁。
\n\n方法3:void运算符
\n\n一个鲜为人知但优雅的方法是使用void 0:
if (x === void 0) {\n console.log('x undefined');\n}\n\n\nvoid运算符计算表达式并返回undefined。void 0是获取纯净undefined的最短方式,且不依赖于全局变量。
何时有用?
\n- \n
- 在压缩代码中(节省字节) \n
- 在需要防止
undefined被重写的库中 \n - 在函数式编程中(例如,在Promise链中) \n
缺点:看起来有点奇怪