JavaScript空检查


170

我遇到了以下代码:

function test(data) {
    if (data != null && data !== undefined) {
        // some code here
    }
}

我对JavaScript有点陌生,但是从我在这里阅读过的其他问题来看,我的印象是这段代码没有多大意义。


特别是,该答案指出:

如果您在以外的任何上下文中访问未定义的变量,则会收到错误消息typeof

更新:上面的(引号)答案可能会引起误解。应该说“未声明的变量”,而不是“未定义的变量”

正如我发现的那样,在Ryan♦maericsnwellnhof的答案中,即使没有为函数提供任何参数,也总是声明该参数的变量。这个事实也证明下面列表中的第一项是错误的。


据我了解,可能会遇到以下情况:

  • 调用该函数时不带参数,因此产生data一个未定义的变量,并在上引发错误data != null

  • 该函数专门以null(或undefined)作为其参数来调用,在这种情况下,该函数data != null已经保护了内部代码,因而变得&& data !== undefined无用。

  • 该函数使用非null参数调用,在这种情况下,它将琐碎地传递data != null data !== undefined

问:我的理解正确吗?


我在Firefox的控制台中尝试了以下操作:

--
[15:31:31.057] false != null
[15:31:31.061] true
--
[15:31:37.985] false !== undefined
[15:31:37.989] true
--
[15:32:59.934] null != null
[15:32:59.937] false
--
[15:33:05.221] undefined != null
[15:33:05.225] false
--
[15:35:12.231] "" != null
[15:35:12.235] true
--
[15:35:19.214] "" !== undefined
[15:35:19.218] true

我无法弄清楚data !== undefined 之后 data != null的用法可能有用。


9
只需使用if (data)。这是一种助记符的Javascript方法,用于检查data变量的评估结果是否为true。undefined,,nullfalse,0,空字符串,空数组和(?)没有属性的对象的结果为false,其余为true。
2013年

20
@ J0HN-使用if(data)表示他无法通过false0作为的值data
techfoobar

@ J0HN另外,我提到的相同答案还指出:if(typeof someUndefVar == whatever) -- worksif(someUnderVar) -- error
2013年

2
可能应该是data !== null && data !== undefined,它data != null等效于data != undefined。前一种形式倾向于优先使用,因为它对条件更为明确,而很容易忽略这两种形式nullundefined而后两种情况正在对其进行检查。
zzzzBov

2
顺便说一下,对undefinedIMO的显式测试是一种代码异味。它不是像一样的受保护关键字null,它是一个未定义的变量。这是完全有效的,并且会破坏您的代码:undefined = 1
Izkata

Answers:


106

“未定义的变量”与值不同undefined

未定义的变量:

var a;
alert(b); // ReferenceError: b is not defined

具有以下值的变量undefined

var a;
alert(a); // Alerts “undefined”

当一个函数接受一个参数时,即使它的值为undefined,也总是声明该参数,因此不会有任何错误。您说得对,!= null其次!== undefined是无用的,虽然。


32
data !== null && data !== undefined会有意义的。
bfavaretto

@bfavaretto:是的,所以实际上可能是一个错字。但是你永远不会知道……:D
Ry-

1
正如我所想,感谢您的澄清。另外,我认为这不是错字。我在整个脚本中运行了一个“ 发现并计数 ”,发现了10次,所以...我想作者也需要对此进行说明。
2013年

2
在上面写下我的评论:实际上,data != null将同时检查nullundefined(但有趣的是,仅检查nullundefined,而不检查其他虚假值)。
bfavaretto

90

在JavaScript中,null是一个特殊的单例对象,有助于发信号表示“无值”。您可以通过比较来测试它,并且像在JavaScript中一样,使用===操作符避免混淆类型强制是一种很好的做法:

var a = null;
alert(a === null); // true

正如@rynah提到的那样,“未定义”在JavaScript中有点令人困惑。但是,typeof(x)即使“ x”不是声明的变量,也总是可以安全地测试the 是否为字符串“ undefined”:

alert(typeof(x) === 'undefined'); // true

此外,如果变量未初始化,则它们可以具有“未定义的值”:

var y;
alert(typeof(y) === 'undefined'); // true

放在一起,您的支票应如下所示:

if ((typeof(data) !== 'undefined') && (data !== null)) {
  // ...

但是,由于总是定义变量“数据”,因为它是形式函数参数,因此不需要使用“ typeof”运算符,并且可以安全地直接与“未定义的值”进行比较。

function(data) {
  if ((data !== undefined) && (data !== null)) {
    // ...

此代码段的意思是说“如果函数是用已定义且不为null的参数调用的……”


5
为什么它看起来像有关系吗?!= nullnull和以外的所有值都将为true undefined,并且我们确定已声明此变量。typeof在其他情况下甚至可能很危险-如果您键入错误的变量名该怎么办?由于没有错误,因此很长一段时间都不会被发现。
Ry-

@maerics因此,如果我正确地遵循了您的回答,那么在上述情况下的空检查中,您将完全不使用!=,仅进行严格的比较!==
2012年

@rynah:我想对OP的整体解决方案了解不多,以了解是否适合使用null测试,但我确实做了编辑以提及使用“ typeof”是不必要的事实。
maerics 2013年

@afsantos:实际上,我不认为很多(任何?)值都将转换为null;但是,最好使用严格的比较(===),除非您真的知道自己在做什么,并希望在转换后进行比较(==)。
2013年

1
@Izkata:删除任何尝试重新定义的库undefined。另外,iPad上的Safari在任何情况下都不会这样做。你甚至不能delete window.undefined
Ry-

10

在您的情况下使用data==null(仅适用于null和undefined-在第二张图片上将焦点集中在null / undefined的行/列上)

这是全部(src):

如果

在此处输入图片说明

==(其否定!=

在此处输入图片说明

===(其否定!==

在此处输入图片说明


8

问:调用该函数时不带参数,因此使数据成为未定义的变量,并在数据!= null上引发错误。

答:是的,data将设置为undefined。请参见规范的10.5节“声明绑定实例化 ”。但是访问未定义的值不会引发错误。您可能会将其与在严格模式下访问未声明的变量混淆,这确实会引发错误。

问:该函数专门以null(或undefined)作为参数调用,在这种情况下,data!= null已经保护了内部代码,使&& data!== undefined无效。

问:使用非空参数调用该函数,在这种情况下,它将琐碎地传递data!= null和data!== undefined。

答:正确。请注意,以下测试是等效的:

data != null
data != undefined
data !== null && data !== undefined

请参见本规范的11.9.3节“抽象平等比较算法”第11.9.6节“严格平等比较算法 ”。


我没有与未声明的变量混淆,当没有提供参数时,我真的不知道它是如何工作的。我坚信这data根本就不存在,而不是设置为undefined。我感谢您的澄清,这些参考资料帮助我更详细地了解了两种平等的工作方式。
2012年

3

我认为,测试变量以获取不期望的值通常不是一个好主意。因为测试如您所愿,您可以考虑将其写入禁止值黑名单。但是,如果您忘记列出所有禁止值怎么办?甚至您也可以通过传递意外值来破解您的代码。因此,更合适的方法是将其列入白名单-仅针对期望值测试变量,而不是意外变量。例如,如果您希望数据值是一个字符串,而不是:

function (data) {
  if (data != null && data !== undefined) {
    // some code here
    // but what if data === false?
    // or data === '' - empty string?
  }
}

做这样的事情:

function (data) {
  if (typeof data === 'string' && data.length) {
    // consume string here, it is here for sure
    // cleaner, it is obvious what type you expect
    // safer, less error prone due to implicit coercion
  } 
}

2

typeof foo === "undefined"与有所不同foo === undefined,请不要混淆它们。typeof foo === "undefined"是您真正需要的。另外,使用!==代替!=

因此该语句可以写成

function (data) {
  if (typeof data !== "undefined" && data !== null) {
    // some code here
  }
}

编辑:

您不能使用foo === undefined未声明的变量。

var t1;

if(typeof t1 === "undefined")
{
  alert("cp1");
}

if(t1 === undefined)
{
  alert("cp2");
}

if(typeof t2 === "undefined")
{
  alert("cp3");
}

if(t2 === undefined) // fails as t2 is never declared
{
  alert("cp4");
}

1
好的,但是在这种情况下声明了变量,所以出了什么问题?
Ry-

我个人觉得foo === undefined使用危险。它使您的代码在尝试防止的相同条件下失败。

我说的是有关函数的参数。另请参阅我的其他评论
Ry-

1
为什么要对此vo之以鼻‽第一句话是正确而重要的区别!
2013年

1
@Izkata:因为没有对初始声明的解释。foo === undefined在OP的情况下是完全可以接受的(假设undefined尚未被覆盖)。答案也无法解释为什么 !==应使用代替!=
马特

1

测试的简单方法是:

function (data) {
    if (data) { // check if null, undefined, empty ...
        // some code here
    }
}

5
这个测试不取决于上下文吗?我的意思是,如果预期的类型data是字符串,则此测试将对空字符串返回false,这可能合适也可能不合适(该函数可能希望以某种方式处理空字符串)。
2013年

5
除非如果“数据”具有值""or 0NaN(或其他),则将跳过“ if”块;这可能不是OP的意图。
2013年

抱歉@afsantos,我没有看到您的评论,如果您想在数据未定义时为false,则为null…除了date为空时,您需要创建另一个var toTest = data; 与第一个类似的另一个测试:if(toTest ==“”){//这里有一些代码}
Kadiri

-5
var a;
alert(a); //Value is undefined

var b = "Volvo"; 
alert(b); //Value is Volvo

var c = null;
alert(c); //Value is null

4
请添加一些解释,以解释这是什么意思。
Ry-

这并不能真正检查null
user4642212 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.