ChatGPT解决这个技术问题 Extra ChatGPT

JavaScript 空值检查

我遇到了以下代码:

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

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

特别是,这个答案指出

如果您在除 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

R
Ry-

“未定义变量”不同于值 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
正如我所想,感谢您的澄清。另外,我不认为这是一个错字。我在整个脚本中运行了一个查找和计数,它发现了 10 次出现,所以......我想作者也需要对此进行澄清。
把我的评论放在上面:实际上,data != null 会同时检查 nullundefined(但有趣的是,只检查 nullundefined,而不是其他虚假值)。
m
maerics

在 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)) {
    // ...

该片段相当于说“如果使用已定义且不为空的参数调用函数......”


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

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

function test(data) { if (data != null) { console.log('Data: ', data); } } 测试(); // data=undefined test(null); // data=null test(undefined); // data=undefined test(0);测试(假);测试(“某事”);

这里有所有 (src):

如果

https://i.stack.imgur.com/uS5qE.png

==(它的否定!=)

https://i.stack.imgur.com/nkpj6.png

===(它的否定!==)

https://i.stack.imgur.com/DIqvq.png


n
nwellnhof

问:该函数在没有参数的情况下被调用,从而使 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。我感谢您的澄清,这些参考资料帮助我更详细地了解了这两种平等是如何运作的。
佚名

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 没有被覆盖)。答案也未能解释为什么应使用 !== 代替 !=
佚名

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

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

K
Kadiri

进行测试的简单方法是:

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

这个测试不是上下文相关的吗?我的意思是,如果 data 的预期类型是字符串,则此测试在空字符串上返回 false,这可能合适,也可能不合适(函数可能希望以某种方式处理空字符串)。
除非“data”的值为 ""0NaN(或其他),否则将跳过“if”块;这可能是也可能不是OP的意图。
抱歉@afsantos,我没有看到你的评论,如果你想在 data 未定义时得到 false,null ...除非 date 为空,你需要创建另一个 var toTest = data;在第一个测试之后进行另一个测试,例如: if(toTest=="") { // 这里有一些代码 }
b
benka
var a;
alert(a); //Value is undefined

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

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

请添加一些关于这应该是什么意思的解释。
这并没有真正检查 null