简体   繁体   English

如何检查 JavaScript 中的未定义或 null 变量?

[英]How to check for an undefined or null variable in JavaScript?

We are frequently using the following code pattern in our JavaScript code我们在 JavaScript 代码中经常使用以下代码模式

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

Is there a less verbose way of checking that has the same effect?是否有更简洁的检查方法具有相同的效果?

According to some forums and literature saying simply the following should have the same effect.根据一些论坛和文献的说法,下面的内容应该具有相同的效果。

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

Unfortunately, Firebug evaluates such a statement as error on runtime when some_variable is undefined, whereas the first one is just fine for it.不幸的是,当some_variable未定义时, Firebug在运行时将这样的语句评估为错误,而第一个就可以了。 Is this only an (unwanted) behavior of Firebug or is there really some difference between those two ways?这只是 Firebug 的一种(不需要的)行为,还是这两种方式之间真的存在一些区别?

I think the most efficient way to test for "value is null or undefined " is我认为测试“值为nullundefined ”的最有效方法是

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

So these two lines are equivalent:所以这两行是等价的:

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

Note 1注1

As mentioned in the question, the short variant requires that some_variable has been declared, otherwise a ReferenceError will be thrown.如问题中所述,短变体要求已声明some_variable ,否则将抛出 ReferenceError 。 However in many use cases you can assume that this is safe:但是,在许多用例中,您可以假设这是安全的:

check for optional arguments:检查可选参数:

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

check for properties on an existing object检查现有对象的属性

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

On the other hand typeof can deal with undeclared global variables (simply returns undefined ).另一方面typeof可以处理未声明的全局变量(简单地返回undefined )。 Yet these cases should be reduced to a minimum for good reasons, as Alsciende explained.然而,正如 Alsciende 解释的那样,出于充分的理由,这些案例应该减少到最低限度。

Note 2笔记2

This - even shorter - variant is not equivalent:这个 - 甚至更短 - 变体是等价的:

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

so所以

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

Note 3注3

In general it is recommended to use === instead of == .一般来说,建议使用===而不是== The proposed solution is an exception to this rule.建议的解决方案是该规则的一个例外。 The JSHint syntax checker even provides the eqnull option for this reason.由于这个原因,JSHint语法检查器甚至提供了eqnull选项。

From the jQuery style guide :来自jQuery 风格指南

Strict equality checks (===) should be used in favor of ==.应该使用严格的相等检查 (===) 来支持 ==。 The only exception is when checking for undefined and null by way of null.唯一的例外是在通过 null 检查未定义和 null 时。

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

EDIT 2021-03:编辑 2021-03:

Nowadays most browsers support the Nullish coalescing operator ( ?? ) and the Logical nullish assignment (??=) , which allows a more concise way to assign a default value if a variable is null or undefined, for example:现在大多数浏览器都支持Nullish 合并运算符 ( ?? )Logical nullish assignment (??=) ,如果变量为 null 或未定义,则可以更简洁地分配默认值,例如:

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

can be written as any of these forms可以写成这些形式中的任何一种

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

You have to differentiate between cases:您必须区分不同的情况:

  1. Variables can be undefined or undeclared .变量可以是undefinedundeclared You'll get an error if you access an undeclared variable in any context other than typeof .如果您在typeof以外的任何上下文中访问未声明的变量,您将收到错误消息。
if(typeof someUndeclaredVar == whatever) // works
if(someUndeclaredVar) // throws error

A variable that has been declared but not initialized is undefined .已声明但未初始化的变量是undefined

let foo;
if (foo) //evaluates to false because foo === undefined
  1. Undefined properties , like someExistingObj.someUndefProperty .未定义的属性,例如someExistingObj.someUndefProperty An undefined property doesn't yield an error and simply returns undefined , which, when converted to a boolean, evaluates to false . undefined 属性不会产生错误,只会返回undefined ,当转换为布尔值时,其计算结果为false So, if you don't care about 0 and false , using if(obj.undefProp) is ok.所以,如果你不关心0false ,使用if(obj.undefProp)是可以的。 There's a common idiom based on this fact:基于这个事实有一个常见的成语:

     value = obj.prop || defaultValue

    which means "if obj has the property prop , assign it to value , otherwise assign the default value defautValue ".这意味着“如果obj具有属性prop ,则将其分配给value ,否则分配默认值defautValue ”。

    Some people consider this behavior confusing, arguing that it leads to hard-to-find errors and recommend using the in operator instead有些人认为这种行为令人困惑,认为它会导致难以发现的错误,并建议使用in运算符

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

Checking null with normal equality will also return true for undefined.用正常相等检查 null 也将为未定义返回 true。

if (window.variable == null) alert('variable is null or undefined');

JS 平等

This is the only case in which == and != should be used:这是唯一应该使用==!=的情况:

if (val == null) console.log('val is null or undefined')
if (val != null) console.log('val is neither null nor undefined')

For any other comparisons, the strict comparators ( === and !== ) should be used.对于任何其他比较,应使用严格的比较器( ===!== )。

In newer JavaScript standards like ES5 and ES6 you can just say在 ES5 和 ES6 等较新的 JavaScript 标准中,你可以说

> Boolean(0) //false
> Boolean(null)  //false
> Boolean(undefined) //false

all return false, which is similar to Python's check of empty variables. all return false,类似于 Python 对空变量的检查。 So if you want to write conditional logic around a variable, just say因此,如果您想围绕变量编写条件逻辑,只需说

if (Boolean(myvar)){
   // Do something
}

here "null" or "empty string" or "undefined" will be handled efficiently.这里“null”或“empty string”或“undefined”将得到有效处理。

If you try and reference an undeclared variable, an error will be thrown in all JavaScript implementations.如果你尝试引用一个未声明的变量,所有的 JavaScript 实现都会抛出一个错误。

Properties of objects aren't subject to the same conditions.对象的属性不受相同条件的约束。 If an object property hasn't been defined, an error won't be thrown if you try and access it.如果尚未定义对象属性,则尝试访问它时不会引发错误。 So in this situation you could shorten:因此,在这种情况下,您可以缩短:

 if (typeof(myObj.some_property) != "undefined" && myObj.some_property != null)

to

if (myObj.some_property != null)

With this in mind, and the fact that global variables are accessible as properties of the global object ( window in the case of a browser), you can use the following for global variables:考虑到这一点,以及全局变量可以作为全局对象的属性(浏览器的情况下为window )访问的事实,您可以将以下内容用于全局变量:

if (window.some_variable != null) {
    // Do something with some_variable
}

In local scopes, it always useful to make sure variables are declared at the top of your code block, this will save on recurring uses of typeof .在本地范围内,确保在代码块的顶部声明变量总是有用的,这将节省typeof的重复使用。

Firstly you have to be very clear about what you test.首先,您必须非常清楚您测试的内容。 JavaScript has all sorts of implicit conversions to trip you up, and two different types of equality comparator: == and === . JavaScript 有各种各样的隐式转换来绊倒你,还有两种不同类型的相等比较器: =====

A function, test(val) that tests for null or undefined should have the following characteristics:测试nullundefined的函数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

Let's see which of the ideas here actually pass our test.让我们看看这里的哪些想法实际上通过了我们的测试。

These work:这些工作:

val == null
val === null || val === undefined
typeof(val) == 'undefined' || val == null
typeof(val) === 'undefined' || val === null

These do not work:这些不起作用:

typeof(val) === 'undefined'
!!val

I created a jsperf entry to compare the correctness and performance of these approaches.我创建了一个jsperf 条目来比较这些方法的正确性和性能 Results are inconclusive for the time being as there haven't been enough runs across different browsers/platforms.结果暂时还没有定论,因为在不同的浏览器/平台上运行的次数还不够。 Please take a minute to run the test on your computer!请花一点时间在您的计算机上运行测试!

At present, it seems that the simple val == null test gives the best performance.目前,似乎简单的val == null测试提供了最好的性能。 It's also pretty much the shortest.它也几乎是最短的。 The test may be negated to val != null if you want the complement.如果您想要补码,测试可能会被否定为val != null

这是使用 Array includes()方法的另一种方法:

[undefined, null].includes(value)

Since there is no single complete and correct answer, I will try to summarize:由于没有一个完整且正确的答案,我将尝试总结:

In general, the expression:一般来说,表达式:

if (typeof(variable) != "undefined" && variable != null)

cannot be simplified, because the variable might be undeclared so omitting the typeof(variable) != "undefined" would result in ReferenceError.无法简化,因为variable可能未声明,因此省略typeof(variable) != "undefined"会导致 ReferenceError。 But, you can simplify the expression according to the context :但是,您可以根据上下文简化表达式

If the variable is global , you can simplify to:如果variableglobal ,您可以简化为:

if (window.variable != null)

If it is local , you can probably avoid situations when this variable is undeclared, and also simplify to:如果它是local ,您可能可以避免未声明此变量的情况,并且还可以简化为:

if (variable != null)

If it is object property , you don't have to worry about ReferenceError:如果是对象属性,就不用担心ReferenceError:

if (obj.property != null)

This is an example of a very rare occasion where it is recommended to use == instead of === .这是一个非常罕见的例子,建议使用==而不是=== Expression somevar == null will return true for undefined and null , but false for everything else (an error if variable is undeclared).表达式somevar == null将为undefinednull返回 true ,但对于其他所有内容返回 false (如果变量未声明,则会出错)。

Using the != will flip the result, as expected.正如预期的那样,使用!=将翻转结果。

Modern editors will not warn for using == or != operator with null , as this is almost always the desired behavior.现代编辑器不会警告将==!=运算符与null一起使用,因为这几乎总是所需的行为。

Most common comparisions:最常见的比较:

undeffinedVar == null     // true
obj.undefinedProp == null // true
null == null              // true
0 == null                 // false
'0' == null               // false
'' == null                // false

Try it yourself:自己试试:

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 },
]);

You can just check if the variable has a value or not.您可以检查变量是否有值。 Meaning,意义,

if( myVariable ) {
//mayVariable is not :
//null
//undefined
//NaN
//empty string ("")
//0
//false

}

If you do not know whether a variable exists (that means, if it was declared) you should check with the typeof operator.如果你不知道一个变量是否存在(也就是说,如果它被声明了)你应该检查 typeof 操作符。 eg例如

if( typeof myVariable !== 'undefined' ) {
    // myVariable will get resolved and it is defined
}

与您所拥有的类似,您可以执行类似的操作

if (some_variable === undefined || some_variable === null) { do stuff }

whatever yyy is undefined or null, it will return true无论yyy是 undefined 还是 null,它都会返回 true

if (typeof yyy == 'undefined' || !yyy) {
    console.log('yes');
} else {
    console.log('no');
}

yes是的

if (!(typeof yyy == 'undefined' || !yyy)) {
    console.log('yes');
} else {
    console.log('no');
}

no

Open the Developer tools in your browser and just try the code shown in the below image.在浏览器中打开开发人员工具,然后尝试下图中显示的代码。

图1 图2

If the purpose of the if statement is to check for null or undefined values before assigning a value to a variable, you can make use of the Nullish Coalescing Operator .如果 if 语句的目的是在将值分配给变量之前检查nullundefined的值,则可以使用Nullish Coalescing Operator According to the data from caniuse , it should be supported by around 85% of the browsers(as of January 2021).根据caniuse的数据,大约 85% 的浏览器应该支持它(截至 2021 年 1 月)。 An example of the operator is shown below:运算符示例如下所示:

const a = some_variable ?? '';

This will ensure that the variable will be assigned to an empty string (or any other default value) if some_variable is null or undefined .如果some_variablenullundefined ,这将确保将变量分配给空字符串(或任何其他默认值)。

This operator is most suited for your use case, as it does not return the default value for other types of falsy value such as 0 and '' .此运算符最适合您的用例,因为它不会返回其他类型的假值(例如0''的默认值。

As mentioned in one of the answers, you can be in luck if you are talking about a variable that has a global scope.如其中一个答案所述,如果您谈论的是具有全局范围的变量,那么您可能会很幸运。 As you might know, the variables that you define globally tend to get added to the windows object.您可能知道,您在全局范围内定义的变量往往会添加到 windows 对象中。 You can take advantage of this fact so lets say you are accessing a variable called bleh, just use the double inverted operator (!!)您可以利用这一事实,假设您正在访问一个名为 bleh 的变量,只需使用双反转运算符 (!!)

!!window['bleh'];

This would return a false while bleh has not been declared AND assigned a value.当 bleh 没有被声明并赋值时,这将返回一个 false。

In order to understand, Let's analyze what will be the value return by the Javascript Engine when converting undefined , null and ''(An empty string also).为了理解,我们来分析一下 Javascript 引擎在转换 undefined 、 null 和 ''(也是空字符串)时返回的值是什么。 You can directly check the same on your developer console.你可以直接在你的开发者控制台上检查。

在此处输入图像描述

You can see all are converting to false , means All these three are assuming 'lack of existence' by javascript.您可以看到所有都转换为 false ,这意味着所有这三个都假设 javascript '不存在'。 So you no need to explicitly check all the three in your code like below.因此,您无需像下面那样显式检查代码中的所有三个。

if (a === undefined || a === null || a==='') {
    console.log("Nothing");
} else {
    console.log("Something");
}

Also I want to point out one more thing.另外我想指出一件事。

What will be the result of Boolean(0)? Boolean(0) 的结果是什么?

Of course false.当然是假的。 This will create a bug in your code when 0 is a valid value in your expected result.当 0 是您预期结果中的有效值时,这将在您的代码中创建一个错误。 So please make sure you check for this when you write the code.因此,请确保在编写代码时检查这一点。

I have done this using this method我已经使用这种方法做到了这一点

save the id in some variable将 id 保存在某个变量中

var someVariable = document.getElementById("someId");

then use if condition然后使用 if 条件

if(someVariable === ""){
 //logic
} else if(someVariable !== ""){
 //logic
}

In ES5 or ES6 if you need check it several times you cand do:在 ES5 或 ES6 中,如果你需要多次检查,你可以这样做:

 const excluded = [null, undefined, '']; if (!exluded.includes(varToCheck) { // it will bee not null, not undefined and not void string }

This is also a nice (but verbose) way of doing it:这也是一种很好的(但冗长的)方式:

if(someObject.someMember ?? null === null) {
  // bladiebla
}

It's very clear what's happening and hard to misunderstand.发生的事情非常清楚,而且很难被误解。 And that can be VERY important!这可能非常重要! :-) :-)

This uses the ??这使用?? operator ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator ).运算符( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator )。 If the value of someObject.someMember is null or undefined , the ??如果someObject.someMember的值为nullundefined ,则?? operator kicks in and will make the value null .运营商启动并将值null

TBH, I like the explicitness of this thing, but I usualle prefer someObject.someMember == null , it's more readable and skilled JS developers probably know what's going on here. TBH,我喜欢这件事的明确性,但我通常更喜欢someObject.someMember == null ,它更具可读性和熟练的 JS 开发人员可能知道这里发生了什么。

 let varToCheck = ""; //U have to define variable firstly ,or it throw error const excluded = [null, undefined, ""]; if (!excluded.includes(varToCheck)) { // it will bee not null, not undefined and not void string console.log("pass"); } else { console.log("fail"); }

for example I copy vladernn's answer to test, u can just click button "Copy snippets to answer" to test too .例如,我复制 vladernn 的答案进行测试,您也可以单击“复制片段以回答”按钮进行测试。

Testing nullity ( if (value == null) ) or non-nullity ( if (value != null) ) is less verbose than testing the definition status of a variable.测试空值( if (value == null) )或非空值( if (value != null) )比测试变量的定义状态更简单。

Moreover, testing if (value) (or if( obj.property) ) to ensure the existence of your variable (or object property) fails if it is defined with a boolean false value.此外,如果使用布尔false值定义变量(或对象属性),则测试if (value) (或if( obj.property) )以确保变量(或对象属性)的存在会失败。 Caveat emptor :)买者自负 :)

使用 Ramda,您可以简单地执行R.isNil(yourValue) Lodash 和其他帮助库具有相同的功能。

Best way to compare undefined or null or 0 with ES5 and ES6 standards将 undefined 或 null 或 0 与 ES5 和 ES6 标准进行比较的最佳方法

 if ((Boolean(some_variable_1) && Boolean(some_variable_2)) === false) {
    // do something
    }

You can make use of lodash library.您可以使用lodash库。

_.isNil(value) gives true for both null and undefined _.isNil(value)nullundefined都给出true

Test on - https://bazinga.tools/lodash测试 - https://bazinga.tools/lodash

在此处输入图像描述

You must define a function of this form:您必须定义这种形式的函数:

validate = function(some_variable){
    return(typeof(some_variable) != 'undefined' && some_variable != null)
}

Both values can be easily distinguished by using the strict comparison operator.使用严格比较运算符可以轻松区分这两个值。

Sample Code:示例代码:

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.");
    }   
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM