如何检查JavaScript中的未定义或空variables?
我们在JavaScript代码中经常使用以下代码模式
if (typeof(some_variable) != 'undefined' && some_variable != null) { // Do something with some_variable }
有没有一个较为详细的检查方法,具有相同的效果?
根据一些论坛和文献的说法,简单地说以下几点应该有同样的效果。
if (some_variable) { // Do something with some_variable }
不幸的是,当some_variable
未定义时, Firebug会评估运行时错误等语句,而第一个语句正好适合它。 这只是萤火虫(不需要)的行为,还是两者之间有一些区别?
你必须区分两种情况
1)未定义的variables ,如“foo”。 如果在typeof以外的任何上下文中访问未定义的variables,将会出错。
if(typeof someUndefVar == whatever) -- works if(someUndefVar) -- error
所以,对于variables来说,检查types是必须的。 另一方面,它只是很less需要 – 你通常知道你的variables是否定义。
2)未定义的属性 ,像someExistingObj.someUndefProperty
。 一个未定义的属性不会产生一个错误,并简单地返回“未定义”,当它被转换为布尔值时,它的计算结果为false。 所以,如果你不关心“0”和“假”, if(obj.undefProp)
。 基于这个事实,有一个常见的习惯用法:
value = obj.prop || defaultValue
这意味着“如果obj有一个道具,使用,否则默认”。
有人认为这种行为混乱,认为它导致难以find的错误,并推荐使用在运营商
value = ('prop' in obj) ? obj.prop : defaultValue
我认为testing“值为null
或undefined
”的最有效方法是
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
,否则会引发ReferenceError。 但是,在许多使用情况下,您可以假设这是安全的:
检查可选参数:
function(foo){ if( foo == null ) {...}
检查现有对象上的属性
if(my_obj.foo == null) {...}
另一方面, typeof
可以处理未声明的全局variables(简单地返回undefined
)。 但正如Alsciende解释的那样,这些情况应该尽可能减less到最低限度。
笔记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
一般来说,build议使用===
而不是==
。 build议的解决scheme是这个规则的例外。 eqnull
语法检查器甚至为此提供了eqnull
选项。
从jQuery风格指南 :
应该使用严格的等式检查(===)来支持==。 唯一的例外是检查未定义和null的空方式。
// Check for both undefined and null values, for some important reason. undefOrNull == null;
如果您尝试引用未声明的variables,则会在所有JavaScript实现中引发错误。
对象的属性不受相同条件的限制。 如果一个对象属性没有被定义,那么当你尝试访问它时,将不会抛出一个错误。 所以在这种情况下你可以缩短:
if (typeof(myObj.some_property) != "undefined" && myObj.some_property != null)
至
if (myObj.some_property != null)
考虑到这一点以及全局variables可作为全局对象的属性(浏览器window
访问的事实,可以使用以下全局variables:
if (window.some_variable != null) { // Do something with some_variable }
在本地范围内,确保variables在代码块的顶部被声明是非常有用的,这将节省typeof
重复使用。
使用正常的相等性检查null也会返回true以表示未定义。
if (window.variable == null) alert('variable is null or undefined');
在新的JavaScript标准,如ES5和ES6,你可以说
> Boolean(0) //false > Boolean(null) //false > Boolean(undefined) //false
全部返回false,这与Python的空variables检查类似。 所以,如果你想写一个variables的条件逻辑,只要说
if (Boolean(myvar)){ // Do something }
这里“空”或“空string”或“未定义”将被有效地处理。
首先,你必须非常清楚你的testing。 JavaScript有各种各样的隐式转换来引发你,以及两种不同types的相等比较器: ==
和===
。
testingnull
或undefined
的函数test(val)
应该具有以下特征:
test(null) => true test(undefined) => true test(0) => false test(1) => false test(true) => false test(false) => false test('s') => false test([]) => false
让我们看看这里的哪个想法实际上通过了我们的testing。
这些工作:
val == null val === null || val === undefined typeof(val) == 'undefined' || val == null typeof(val) === 'undefined' || val === null
这些不起作用:
typeof(val) === 'undefined' !!val
我创build了一个jsperf条目来比较这些方法的正确性和性能 。 目前的结果是不确定的,因为在不同的浏览器/平台上没有足够的运行。 请花一分钟在计算机上运行testing!
目前看来,简单的val == null
testing给出了最好的性能。 这也是最短的。 如果你想要补码,testing可能被否定为val != null
。
既然没有完整正确的答案,我会尽量总结一下:
一般来说,expression式:
if (typeof(variable) != "undefined" && variable != null)
不能被简化,因为variable
可能是未声明的,所以省略typeof(variable) != "undefined"
会导致ReferenceError。 但是, 您可以根据上下文简化expression式 :
如果variable
是全局 variable
则可以简化为:
if (window.variable != null)
如果它是本地的 ,你可以避免这个variables未被声明的情况,也可以简化为:
if (variable != null)
如果是对象属性 ,则不必担心ReferenceError:
if (obj.property != null)
你可以检查variables是否有值。 含义,
if( myVariable ) { //mayVariable is not : //null //undefined //NaN //empty string ("") //0 //false }
如果你不知道一个variables是否存在(也就是说,如果声明的话),你应该检查typeof操作符。 例如
if( typeof myVariable !== 'undefined' ) { // myVariable will get resolved and it is defined }
无论yyy是未定义还是为空,它都会返回true
if (typeof yyy == 'undefined' || !yyy) { console.log('yes'); } else { console.log('no'); }
是
if (!(typeof yyy == 'undefined' || !yyy)) { console.log('yes'); } else { console.log('no'); }
没有
正如其中一个答案所提到的,如果您正在讨论一个具有全局范围的variables,那么您可能会很幸运。 正如你可能知道的那样,全局定义的variables往往会被添加到windows对象中。 你可以利用这个事实,所以假设你正在访问一个名为bleh的variables,只需使用双倒数运算符(!!)
!!window['bleh'];
这将返回一个错误,而bleh尚未被声明和赋值。
与testingvariables的定义状态相比,testing无效( if (value == null)
)或非nullity( if (value != null)
)不那么冗长。
此外, if (value)
确定variables(或对象属性)的存在( if (value)
(或if( obj.property)
)testingif (value)
失败,如果它是一个布尔值false
值定义。 买者自负 :)
使用严格的比较运算符可以很容易地区分这两个值:
工作示例:
http://www.thesstech.com/tryme?filename=nullandundefined
示例代码:
function compare(){ var a = null; //variable assigned null value var b; // undefined if (a === b){ document.write("a and b have same datatype."); } else{ document.write("a and b have different datatype."); } }
您必须定义这种forms的function:
validate = function(some_variable){ return(typeof(some_variable) != 'undefined' && some_variable != null) }