我遇到了以下代码:
function test(data) {
if (data != null && data !== undefined) {
// some code here
}
}
我对 JavaScript 有点陌生,但是,从我在这里阅读的其他问题来看,我的印象是这段代码没有多大意义。
特别是,这个答案指出
如果您在除 typeof 之外的任何上下文中访问未定义的变量,则会收到错误消息。
更新:上面的(引用)答案可能具有误导性。它应该说“一个未声明的变量”,而不是“一个未定义的变量”。
正如我发现的那样,在 Ryan ♦、maerics 和 nwellnhof 的答案中,即使没有为函数提供参数,它的参数变量也总是被声明的。这一事实也证明了下面列表中的第一项是错误的。
据我了解,可能会遇到以下几种情况:
该函数在没有参数的情况下被调用,从而使 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 助记方法。 undefined
、null
、false、0、空字符串、空数组和没有属性的 (?) 对象的计算结果为 false,其余为 true。
if(data)
意味着他不能将 false
或 0
作为 data
的值。
if(typeof someUndefVar == whatever) -- works
和 if(someUnderVar) -- error
。
data !== null && data !== undefined
,相当于 data != null
,相当于 data != undefined
。前一种形式往往受到青睐,因为它对条件更明确,而很容易忽略 null
和 undefined
都在使用后两个条件进行检查。
undefined
的显式测试是 IMO 代码异味。它不是像 null
这样的受保护关键字,它是一个碰巧未定义的变量。这是完全有效的,并且会破坏您的代码:undefined = 1
“未定义变量”不同于值 undefined
。
一个未定义的变量:
var a;
alert(b); // ReferenceError: b is not defined
值为 undefined
的变量:
var a;
alert(a); // Alerts “undefined”
当一个函数接受一个参数时,该参数总是被声明,即使它的值为 undefined
,所以不会有任何错误。不过,您对 != null
和 !== undefined
无用是正确的。
在 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
对除 null
和 undefined
之外的所有值都为真,并且我们确定已声明此变量。 typeof
在其他情况下甚至可能很危险——如果您输入错误的变量名怎么办?这可能会在很长一段时间内未被发现,因为没有错误。
!=
,只能使用严格比较,!==
?
===
),除非您真的知道自己在做什么并希望在转换后进行比较 (==
)。
undefined
的库。此外,iPad 上的 Safari 在任何情况下都不会这样做。你甚至不能delete window.undefined
。
在您的情况下使用 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
问:该函数在没有参数的情况下被调用,从而使 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 Algorithm 和 section 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
使用起来很危险。它使您的代码在您试图阻止的相同情况下失败。
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
}
}
进行测试的简单方法是:
function (data) {
if (data) { // check if null, undefined, empty ...
// some code here
}
}
data
的预期类型是字符串,则此测试在空字符串上返回 false,这可能合适,也可能不合适(函数可能希望以某种方式处理空字符串)。
""
或 0
或 NaN
(或其他),否则将跳过“if”块;这可能是也可能不是OP的意图。
var a;
alert(a); //Value is undefined
var b = "Volvo";
alert(b); //Value is Volvo
var c = null;
alert(c); //Value is null
null
。
data !== null && data !== undefined
是有道理的。data != null
会同时检查null
和undefined
(但有趣的是,只检查null
和undefined
,而不是其他虚假值)。