function f (x) {
if (x === undefined) console.log('x is undefined [x === undefined].');
else console.log('x is not undefined [x === undefined.]');
if (typeof(x) === 'undefined') console.log('x is undefined [typeof(x) === \'undefined\'].');
else console.log('x is not undefined [typeof(x) === \'undefined\'].');
// This will throw exception because what the hell is j? It is nowhere to be found.
try
{
if (j === undefined) console.log('j is undefined [j === undefined].');
else console.log('j is not undefined [j === undefined].');
}
catch(e){console.log('Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.');}
// However this will not throw exception
if (typeof j === 'undefined') console.log('j is undefined (typeof(x) === \'undefined\'). We can use this check even though j is nowhere to be found in our source code and it will not throw.');
else console.log('j is not undefined [typeof(x) === \'undefined\'].');
};
如果我们这样调用上面的代码:
f();
输出结果如下:
x is undefined [x === undefined].
x is undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.
如果我们像这样调用上面的代码(实际上是任意值):
f(null);
f(1);
输出将为:
x is not undefined [x === undefined].
x is not undefined [typeof(x) === 'undefined'].
Error!!! Cannot use [j === undefined] because j is nowhere to be found in our source code.
j is undefined (typeof(x) === 'undefined'). We can use this check even though j is nowhere to be found in our source code and it will not throw.
当你这样做检查时:typeof x === 'undefined',您实际上是在问:* 请检查变量x是否在源代码中的某个地方存在(已定义)。*(或多或少)。如果您了解C#或Java,则永远不会执行此类检查,因为如果它不存在,则无法编译。 <== Fiddle Me ==>
var globalVar1;
// This variable is declared, but not defined and thus has the value undefined
console.log(globalVar1 === undefined);
// This variable is not declared and thus will throw a referenceError
console.log(globalVar2 === undefined);
// In this first test, the variable "myVariable1" does not exist yet so creates
// an error if we try and check if its assigned the default value of undefined!
if (myVariable1 === undefined) alert(true);// REFERENCE ERROR!
// Here we can elegantly catch the "undefined" type
// of the missing variable and stop the REFERENCE ERROR using "typeof".
if (typeof myVariable1 === "undefined") alert(true);// true
// Here we have declared the missing variable and notice its
// still an "undefined" type until initialized with a value.
let myVariable1;
if (typeof myVariable1 === "undefined") alert(true);// true
// Lastly, after we assign a value, the type is no longer
// "undefined" so returns false.
myVariable1 = 'hello';
if (typeof myVariable1 === "undefined") alert(true);// false
9条答案
按热度按时间tkqqtvp11#
对于未声明的变量,
typeof foo
将返回字符串文字"undefined"
,而标识检查foo === undefined
将触发错误 “foo is not defined”。对于局部变量(您 * 知道 * 在某处声明),不会发生这样的错误,因此需要进行标识检查。
8fq7wneg2#
我会坚持在任何地方使用
typeof foo === "undefined"
,这永远不会出错。我想jQuery推荐这两种不同方法的原因是它们在jQuery代码所在的函数中定义了自己的
undefined
变量,因此在该函数中undefined
是安全的,不会受到外部的篡改。我还可以想象,有人在某处对这两种不同的方法进行了基准测试,发现foo === undefined
更快,因此决定采用这一方法。**[更新:如注解中所述,与undefined
的比较也略短,这可能是一个考虑因素。]**然而,在实际情况下的增益将是完全微不足道的:这一检查将永远不会成为任何类型的瓶颈,而您所失去的将是巨大的:评估用于比较的主机对象的属性可能抛出错误,而typeof
检查永远不会抛出错误。例如,在IE中使用以下代码来解析XML:
要安全地检查它是否具有
loadXML
方法:另一方面:
更新
typeof
检查的另一个优点是,它还可以处理未声明的变量,而foo === undefined
检查则不能,实际上它会抛出一个ReferenceError
。感谢@LinusKleen提醒我。例如:底线:请始终使用
typeof
检查。r8xiu3jd3#
使用typeof-variant的另一个原因是:可以重新定义
undefined
。typeof variable
的结果不能。更新:请注意,在ES 5中情况并非如此,全局
undefined
是不可配置、不可写的属性:15.1.1全局对象的值属性
[...]
15.1.1.3 未定义
undefined
的值未定义(请参见8.1)。{ 可写:false,可枚举:false,可配置:错误}。
但它仍然可以被局部变量遮蔽:
或参数:
uidvcgyl4#
因为
undefined
并不总是声明的,但是jQuery在它的main函数中声明了undefined
,所以它们在内部使用安全的undefined
值,但是在外部,它们使用typeof
样式来保证安全。gzszwxb45#
谁对
variable === undefined
的性能增益感兴趣,可能会在这里看一看,但它似乎只是一个chrome优化。8hhllhi26#
对于局部变量,使用
localVar === undefined
进行检查将有效,因为它们必须已在局部范围内的某个位置定义,否则将不被视为局部变量。对于非局部变量和未在任何位置定义的变量,检查
someVar === undefined
将抛出异常:* 未捕获的引用错误:j未定义 *这里有一些代码,将澄清我在上面说的话。* 请注意进一步澄清内联注解 *。
如果我们这样调用上面的代码:
输出结果如下:
如果我们像这样调用上面的代码(实际上是任意值):
输出将为:
当你这样做检查时:
typeof x === 'undefined'
,您实际上是在问:* 请检查变量x
是否在源代码中的某个地方存在(已定义)。*(或多或少)。如果您了解C#或Java,则永远不会执行此类检查,因为如果它不存在,则无法编译。<== Fiddle Me ==>
bwleehnv7#
总结:
在全局作用域中,如果变量没有声明或者其值为
undefined
,我们实际上希望返回true:因为在全局范围内,我们不能100%确定变量是否被声明,这可能会给予我们一个referenceError。当我们在未知变量上使用
typeof
运算符时,如果变量没有被声明,我们就不会遇到这个问题:这是由于
typeof
运算符返回字符串undefined
,而变量未声明或当前的值为undefined
,这正是我们想要的。undefined
uyhoqukh8#
JavaScript中“未定义”的含义
这个问题与变量的局部与全局作用域、jQuery决策等无关。
undefined
有两个不同的表达式,以及三种不同的用法,如下所示:1.**“typeof”和“未定义”**类型:没有声明和不存在的变量不会被赋值,但其“类型”为undefined。如果您访问一个甚至不存在的变量,更不用说声明或初始化了,那么访问它时将生成一个引用错误。即使在测试
undefined
的基元默认值时也是如此,该基元默认值在赋值之前一直被赋给声明的变量。因此,检查“typeof”在此情况下,可防止此错误,如下所示:JavaScript中所有被访问但未声明的对象和类型将默认为“undefined”类型。因此,这里的课程是首先尝试检查
typeof
,以防止丢失变量错误!1.
undefined
基元值:在JavaScript中,所有尚未赋值的已声明变量都被赋值为undefined
的 primitve。如果您已经声明了一个变量,但尚未初始化它,则会将其赋值为默认的 * primitve * 类型undefined
。这与“undefined”类型不同。undefined
的基元值是一个 reserved 值,但可以更改。但这并不是这里所要求的。请注意,这里只捕获所有已声明但未初始化的变量:1.对象和
undefined
基元:最后,Object属性的行为与JavaScript中的变量不一样。Object属性在缺失时不会变成未定义的类型,而只是像上面未声明的变量一样被赋以 primitiveundefined
。因此,它们的行为类似于#2:最佳实践
最后......这是一个很好的理由,总是检查所有JavaScript代码中变量的“undefined”类型和
undefined
primitive 值。大多数人会说,你很少需要这两个。可能有一天,一个丢失的变量在一个不存在的库中被访问,并创建一个讨厌的JavaScript引用错误!所以我总是做这个检查,并按照这个顺序,停止JavaScript中的所有错误:mpbci0fu9#
在节点v6.9.1上,
typeof a === 'undefined'
比a === 'undefined'
快大约2倍。