【问题标题】:JavaScript null checkJavaScript 空值检查
【发布时间】:2013-05-16 09:09:57
【问题描述】:

我遇到了以下代码:

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

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


特别是,this answer 指出

如果您在除typeof 之外的任何上下文中访问未定义变量,您将收到错误消息。

更新:上面的答案(引用)可能具有误导性。它应该说«一个未声明的变量»,而不是«一个未定义的变量»

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


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

  • 函数在没有参数的情况下被调用,因此使data 成为未定义的变量,并在data != null 上引发错误。

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

    李>
  • 使用非空参数调用函数,在这种情况下,它会轻松传递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 after data != null 有什么用处。

【问题讨论】:

  • 只需使用if (data)。这是检查 data 变量是否为真的 Javascript 助记方法。 undefinednull、false、0、空字符串、空数组和 (?) 没有属性的对象评估为 false,其余为 true。
  • @J0HN - 使用if(data) 意味着他不能将false0 作为data 的值传递。
  • @J0HN 另外,我提到的相同答案还指出:if(typeof someUndefVar == whatever) -- worksif(someUnderVar) -- error
  • 应该是data !== null && data !== undefined,相当于data != null,相当于data != undefined。前一种形式往往受到青睐,因为它对条件更明确,而很容易忽略nullundefined 都在与后两种条件进行检查。
  • 顺便说一下,undefined 的显式测试是 IMO 代码异味。它不是像null 这样的受保护关键字,它是一个碰巧未定义的变量。这是完全有效的,并且会破坏您的代码:undefined = 1

标签: javascript null undefined null-check


【解决方案1】:

“未定义变量”不同于值undefined

一个未定义的变量:

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

值为undefined的变量:

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

当一个函数接受一个参数时,即使它的值是undefined,这个参数总是被声明,所以不会有任何错误。不过,!= null 后面跟着 !== undefined 没用,你是对的。

【讨论】:

  • 不过,data !== null && data !== undefined 是有道理的。
  • @bfavaretto:是的,所以它实际上可能是一个错字。但你永远不知道……:D
  • 正如我所想,感谢您的澄清。另外,我不认为这是一个错字。我在整个脚本中运行了 find-and-count,发现出现了 10 次,所以……我想作者也需要对此进行澄清。
  • 从我上面的评论开始:实际上,data != null 会检查nullundefined(但有趣的是,只检查nullundefined,而不是其他虚假值)。
【解决方案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");
}

【讨论】:

  • 好的,但是在这种情况下声明了变量,那有什么问题?
  • 就个人而言,我发现foo === undefined 使用起来很危险。它使您的代码在您试图阻止的相同情况下失败。
  • 我说的是有问题的函数的参数。另请参阅my other comment
  • 为什么这被否决了‽第一句话是正确且重要的区别!
  • @Izkata:因为最初的声明没有解释。 foo === undefined 在 OP 的情况下是完全可以接受的(假设 undefined 没有被覆盖)。答案也无法解释为什么应该使用!== 代替!=
【解决方案3】:

在 JavaScript 中,null 是一个特殊的单例对象,有助于发出“无价值”的信号。您可以通过比较对其进行测试,并且像往常一样在 JavaScript 中,使用 === 运算符以避免混淆类型强制是一种很好的做法:

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

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

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

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

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

综上所述,您的支票应如下所示:

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

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

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

这个 sn-p 相当于说“如果函数是用一个已定义且不为空的参数调用的......”

【讨论】:

  • 为什么应该看起来像那样呢? != null 对除nullundefined 之外的所有值都为真,并且我们确定该变量已声明。 typeof 在其他情况下甚至可能很危险——如果你输入错误的变量名怎么办?这可能会在很长一段时间内未被检测到,因为没有错误。
  • @maerics 所以,如果我正确地遵循了你的答案,在上述情况下的空值检查中,你根本不会使用!=,只有严格比较,!==?
  • @rynah:我认为对 OP 的整体解决方案了解得不够多,无法知道空测试是否合适,但我确实进行了编辑,提到了使用“typeof”是不必要的这一事实。
  • @afsantos:实际上我不认为很多(任何?)值会转换为 null;但是,最好使用严格比较 (===),除非您真的知道自己在做什么并希望在转换后进行比较 (==)。
  • @Izkata:删除任何试图重新定义 undefined 的库。此外,iPad 上的 Safari 在任何情况下都不会这样做。你甚至不能delete window.undefined
【解决方案4】:

进行测试的简单方法是:

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

【讨论】:

  • 这个测试不是上下文相关的吗?我的意思是,如果 data 的预期类型是字符串,则此测试在空字符串上返回 false,这可能合适,也可能不合适(函数可能希望以某种方式处理空字符串)。跨度>
  • 除非“data”的值为""0NaN(或其他),否则“if”块将被跳过;这可能是也可能不是 OP 的意图。
  • 对不起@afsantos,我没有看到你的评论,如果你想在数据未定义时得到 false,null ...除非日期为空,你需要创建另一个var toTest = data; 与第一个测试之后的另一个测试类似:if(toTest=="") { // 这里有一些代码 }
【解决方案5】:

问:该函数在没有参数的情况下被调用,因此使 data 成为未定义的变量,并在 data != null 上引发错误。

答:是的,data 将被设置为未定义。请参阅规范的section 10.5 Declaration Binding Instantiation。但是访问未定义的值不会引发错误。您可能会将此与在严格模式下访问未声明的变量混淆,这确实会引发错误。

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

问:该函数是使用非空参数调用的,在这种情况下,它会简单地传递 data != null 和 data !== undefined 。

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

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

参见规范中的section 11.9.3 The Abstract Equality Comparison Algorithmsection 11.9.6 The Strict Equality Comparison Algorithm

【讨论】:

  • 我并没有对未声明的变量感到困惑,我真的不知道在没有提供参数时它是如何工作的。我确信data 根本不存在,而不是设置为undefined。感谢您的澄清,这些参考资料帮助我更详细地了解了这两种平等是如何运作的。
【解决方案6】:
var a;
alert(a); //Value is undefined

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

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

【讨论】:

  • 请添加一些解释,说明这是什么意思。
  • 这并没有真正检查 null
【解决方案7】:

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

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
  } 
}

【讨论】:

    【解决方案8】:

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

    function test(data) {
        if (data != null) {
            console.log('Data: ', data);
        }
    }
    
    test();          // the data=undefined
    test(null);      // the data=null
    test(undefined); // the data=undefined
    
    test(0); 
    test(false); 
    test('something');

    这里都有 (src):

    如果

    ==(它的否定!=

    ===(它的否定!==

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-05-21
      • 1970-01-01
      • 2011-09-07
      • 1970-01-01
      • 1970-01-01
      • 2017-11-07
      • 2020-05-27
      • 2012-09-22
      相关资源
      最近更新 更多