Tom*_*ana 480 javascript null undefined
我们经常在JavaScript代码中使用以下代码模式
if (typeof(some_variable) != 'undefined' && some_variable != null)
{
// Do something with some_variable
}
Run Code Online (Sandbox Code Playgroud)
是否有一种不那么冗长的检查方式具有相同的效果?
根据一些论坛和文献说,以下应该具有相同的效果.
if (some_variable)
{
// Do something with some_variable
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,当未定义时,Firebug将这样的语句评估为运行时错误some_variable
,而第一个语句就好了.这只是Firebug的一个(不需要的)行为,还是这两种方式之间确实存在一些差异?
mar*_*r10 399
我认为测试"价值是null
或undefined
" 的最有效方法是
if ( some_variable == null ){
// some_variable is either null or undefined
}
Run Code Online (Sandbox Code Playgroud)
所以这两行是等价的:
if ( typeof(some_variable) !== "undefined" && some_variable !== null ) {}
if ( some_variable != null ) {}
Run Code Online (Sandbox Code Playgroud)
注1
正如问题中所提到的,short变量要求some_variable
已声明,否则将抛出ReferenceError.但是在许多用例中,您可以认为这是安全的:
检查可选参数:
function(foo){
if( foo == null ) {...}
Run Code Online (Sandbox Code Playgroud)
检查现有对象的属性
if(my_obj.foo == null) {...}
Run Code Online (Sandbox Code Playgroud)
另一方面typeof
可以处理未声明的全局变量(简单地返回undefined
).然而,正如Alsciende所解释的那样,这些案例应该有充分的理由减少到最低限度.
笔记2
这个 - 甚至更短 - 变体不等同于:
if ( !some_variable ) {
// some_variable is either null, undefined, 0, NaN, false, or an empty string
}
Run Code Online (Sandbox Code Playgroud)
所以
if ( some_variable ) {
// we don't get here if some_variable is null, undefined, 0, NaN, false, or ""
}
Run Code Online (Sandbox Code Playgroud)
注3
一般来说,建议使用===
而不是==
.建议的解决方案是此规则的一个例外.由于这个原因,JSHint语法检查器甚至提供了eqnull
选项.
应使用严格的相等性检查(===)以支持==.唯一的例外是通过null检查undefined和null.
Run Code Online (Sandbox Code Playgroud)// Check for both undefined and null values, for some important reason. undefOrNull == null;
use*_*291 327
您必须区分两种情况:
未定义的变量,如undefined
.如果在除了以外的任何上下文中访问未定义的变量,您将收到错误typeof
.
if(typeof someUndeclaredVar == whatever) // works
if(someUndeclaredVar) // throws error
Run Code Online (Sandbox Code Playgroud)
因此,对于变量,undefined
检查是必须的.另一方面,它很少需要 - 你通常知道你的变量是否被定义.
未定义的属性,如someExistingObj.someUndefProperty
.未定义的属性不会产生错误并且只返回undefined
,当转换为布尔值时,求值为false
.所以,如果你不关心
0
和false
使用if(obj.undefProp)
就可以了.基于这个事实有一个共同的习语:
let foo;
if (foo) //evaluates to false because foo === undefined
Run Code Online (Sandbox Code Playgroud)
这意味着"如果obj
有属性prop
,则分配给它value
,否则分配默认值defautValue
".
有些人认为这种行为令人困惑,认为这会导致难以发现的错误并建议使用in
运营商
value = obj.prop || defaultValue
Run Code Online (Sandbox Code Playgroud)Sem*_*mra 62
对于undefined,使用正常相等性检查null也将返回true.
if (window.variable == null) alert('variable is null or undefined');
Nar*_*ula 29
在较新的JavaScript标准中,例如ES5和ES6,您可以这么说
> Boolean(0) //false
> Boolean(null) //false
> Boolean(undefined) //false
Run Code Online (Sandbox Code Playgroud)
all返回false,类似于Python对空变量的检查.因此,如果您想围绕变量编写条件逻辑,那就说
if (Boolean(myvar)){
// Do something
}
Run Code Online (Sandbox Code Playgroud)
这里"null"或"空字符串"或"未定义"将被有效处理.
And*_*y E 21
如果您尝试引用未声明的变量,则会在所有JavaScript实现中引发错误.
对象的属性不受相同条件的约束.如果尚未定义对象属性,则在尝试访问它时不会引发错误.所以在这种情况下你可以缩短:
if (typeof(myObj.some_property) != "undefined" && myObj.some_property != null)
Run Code Online (Sandbox Code Playgroud)
至
if (myObj.some_property != null)
Run Code Online (Sandbox Code Playgroud)
考虑到这一点,以及全局变量可作为全局对象的属性(window
在浏览器的情况下)可访问的事实,您可以将以下内容用于全局变量:
if (window.some_variable != null) {
// Do something with some_variable
}
Run Code Online (Sandbox Code Playgroud)
在本地范围中,确保变量在代码块的顶部声明总是有用的,这将节省重复使用的时间typeof
.
Dre*_*kes 15
首先,你必须非常清楚你测试的是什么.JavaScript有各种各样的隐式转换,以及两种不同类型的相等比较器:==
和===
.
test(val)
测试null
或undefined
应具有以下特征的函数:
test(null) => true
test(undefined) => true
test(0) => false
test(1) => false
test(true) => false
test(false) => false
test('s') => false
test([]) => false
Run Code Online (Sandbox Code Playgroud)
让我们看看这里的哪些想法实际上通过了我们的测试.
这些工作:
val == null
val === null || val === undefined
typeof(val) == 'undefined' || val == null
typeof(val) === 'undefined' || val === null
Run Code Online (Sandbox Code Playgroud)
这些不起作用:
typeof(val) === 'undefined'
!!val
Run Code Online (Sandbox Code Playgroud)
我创建了一个jsperf条目来比较这些方法的正确性和性能.由于在不同的浏览器/平台上没有足够的运行,因此结果目前尚无定论.请花点时间在您的计算机上运行测试!
目前,似乎简单的val == null
测试提供了最佳性能.它也是最短的.val != null
如果你想要补充,可以否定测试.
这是使用 Array includes()方法的另一种方法:
[undefined, null].includes(value)
Run Code Online (Sandbox Code Playgroud)
由于没有一个完整而正确的答案,因此我将尝试总结一下:
通常,表达式为:
if (typeof(variable) != "undefined" && variable != null)
Run Code Online (Sandbox Code Playgroud)
无法简化,因为variable
可能未声明,因此省略typeof(variable) != "undefined"
将导致ReferenceError。但是,您可以根据上下文简化表达式:
如果variable
是全局,则可以简化为:
if (window.variable != null)
Run Code Online (Sandbox Code Playgroud)
如果它是local,则可以避免未声明此变量的情况,并且还可以简化为:
if (variable != null)
Run Code Online (Sandbox Code Playgroud)
如果它是object property,则不必担心ReferenceError:
if (obj.property != null)
Run Code Online (Sandbox Code Playgroud)
这是唯一==
应使用的情况:
if (val == null) console.log('val is null or undefined')
Run Code Online (Sandbox Code Playgroud)
您可以检查变量是否具有值.含义,
if( myVariable ) {
//mayVariable is not :
//null
//undefined
//NaN
//empty string ("")
//0
//false
}
Run Code Online (Sandbox Code Playgroud)
如果您不知道变量是否存在(即,如果已声明),则应使用typeof运算符进行检查.例如
if( typeof myVariable !== 'undefined' ) {
// myVariable will get resolved and it is defined
}
Run Code Online (Sandbox Code Playgroud)
这是一个非常罕见的例子,建议使用==
代替===
。表达式somevar == null
将返回 trueundefined
和null
,但对于其他所有内容都返回false(如果变量未声明,则为错误)。
!=
正如预期的那样,使用将翻转结果。
现代编辑器不会警告使用==
或!=
运算符null
,因为这几乎总是期望的行为。
最常见的比较:
undeffinedVar == null // true
obj.undefinedProp == null // true
null == null // true
0 == null // false
'0' == null // false
'' == null // false
Run Code Online (Sandbox Code Playgroud)
自己试试:
let undefinedVar;
console.table([
{ test : undefinedVar, result: undefinedVar == null },
{ test : {}.undefinedProp, result: {}.undefinedProp == null },
{ test : null, result: null == null },
{ test : false, result: false == null },
{ test : 0, result: 0 == null },
{ test : '', result: '' == null },
{ test : '0', result: '0' == null },
]);
Run Code Online (Sandbox Code Playgroud)
这也是一种很好的(但很冗长)的方法:
if((someObject.someMember ?? null) === null) {
// bladiebla
}
Run Code Online (Sandbox Code Playgroud)
正在发生的事情非常清楚并且很难误解。这非常重要!:-)
这使用了??
运算符(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator)。someObject.someMember
如果的值为null
or undefined
,则??
运算符将介入并生成该值null
。
说实话,我喜欢这个东西的明确性,但我通常更喜欢它someObject.someMember == null
,它更具可读性,熟练的 JS 开发人员可能知道这里发生了什么。