如何在JavaScript中检查未定义或空变量?

2022-08-29 22:42:14

我们经常在 JavaScript 代码中使用以下代码模式

if (typeof(some_variable) != 'undefined' && some_variable != null)
{
    // Do something with some_variable
}

有没有一种不那么冗长的检查方法具有相同的效果?

根据一些论坛和文献的说法,简单地说,以下内容应该具有相同的效果。

if (some_variable)
{
    // Do something with some_variable
}

不幸的是,Firebug在运行时将此类语句评估为未定义时的错误,而第一个语句则很好。这只是Firebug的(不需要的)行为,还是这两种方式之间真的有一些区别?some_variable


答案 1

我认为测试“价值是或”的最有效方法是nullundefined

if ( some_variable == null ){
  // some_variable is either null or undefined
}

所以这两行是等价的:

if ( typeof(some_variable) !== "undefined" && some_variable !== null ) {}
if ( some_variable != null ) {}

附注 1

如问题中提到的,短变体需要已声明,否则将抛出引用错误。但是,在许多用例中,您可以假设这是安全的:some_variable

检查可选参数:

function(foo){
    if( foo == null ) {...}

检查现有对象的属性

if(my_obj.foo == null) {...}

另一方面可以处理未声明的全局变量(简单地返回)。然而,正如Alsciende所解释的那样,出于充分的理由,这些案件应该减少到最低限度。typeofundefined

附注 2

这个 - 甚至更短 - 变体不是等价的:

if ( !some_variable ) {
  // some_variable is either null, undefined, 0, NaN, false, or an empty string
}

所以

if ( some_variable ) {
  // we don't get here if some_variable is null, undefined, 0, NaN, false, or ""
}

附注 3

通常,建议使用 代替 。建议的解决方案是此规则的例外。出于这个原因,JSHint语法检查器甚至提供了该选项。=====eqnull

来自 jQuery 风格指南

应使用严格的相等性检查 (===) 来支持 ==。唯一的例外是通过 null 检查未定义和 null 时。

// Check for both undefined and null values, for some important reason. 
undefOrNull == null;

编辑2021-03:

如今,大多数浏览器都支持 Nullish 合并运算符 (??Logical nullish 赋值 (??=),它允许在变量为 null 或未定义时以更简洁的方式分配默认值,例如:

if (a.speed == null) {
  // Set default if null or undefined
  a.speed = 42;
}

可以写成这些形式中的任何一种

a.speed ??= 42;
a.speed ?? a.speed = 42;
a.speed = a.speed ?? 42;

答案 2

您必须区分以下情况:

  1. 变量可以是未声明的。如果在 除 以外的任何上下文中访问未声明的变量,则会收到错误。undefinedtypeof
if(typeof someUndeclaredVar == whatever) // works
if(someUndeclaredVar) // throws error

已声明但未初始化的变量是 。undefined

let foo;
if (foo) //evaluates to false because foo === undefined
  1. 未定义的属性,如 .未定义的属性不会产生错误,而只是返回 ,当转换为布尔值时,其计算结果为 。所以,如果你不关心和,使用是可以的。基于这个事实,有一个常见的成语:someExistingObj.someUndefPropertyundefinedfalse0falseif(obj.undefProp)

    value = obj.prop || defaultValue
    

    这意味着“如果具有属性,则将其赋给 ,否则赋值默认值”。objpropvaluedefautValue

    有些人认为这种行为令人困惑,认为它会导致难以发现的错误,并建议使用in运算符代替

    value = ('prop' in obj) ? obj.prop : defaultValue