Javascript 变量 === 未定义与 typeof 变量 === “未定义”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4725603/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 13:47:18  来源:igfitidea点击:

variable === undefined vs. typeof variable === "undefined"

javascriptjqueryundefined

提问by Patrick McElhaney

The jQuery Core Style Guidelinessuggest two different ways to check whether a variable is defined.

jQuery的核心风格指南建议两种不同的方法来检查一个变量是否被定义。

  • Global Variables: typeof variable === "undefined"
  • Local Variables: variable === undefined
  • Properties: object.prop === undefined
  • 全局变量: typeof variable === "undefined"
  • 局部变量: variable === undefined
  • 特性: object.prop === undefined

Why does jQuery use one approach for global variables and another for locals and properties?

为什么 jQuery 对全局变量使用一种方法而对局部变量和属性使用另一种方法?

回答by Linus Kleen

For undeclared variables, typeof foowill return the string literal "undefined", whereas the identity check foo === undefinedwould trigger the error "foo is not defined".

对于未声明的变量,typeof foo将返回字符串文字"undefined",而身份检查foo === undefined将触发错误“foo is not defined”

For local variables (which you knoware declared somewhere), no such error would occur, hence the identity check.

对于局部变量(您知道在某处声明),不会发生此类错误,因此需要进行身份检查。

回答by Tim Down

I'd stick to using typeof foo === "undefined"everywhere. That can never go wrong.

我会坚持在typeof foo === "undefined"任何地方使用。那永远不会出错。

I imagine the reason why jQuery recommends the two different methods is that they define their own undefinedvariable within the function that jQuery code lives in, so within that function undefinedis safe from tampering from outside. I would also imagine that someone somewhere has benchmarked the two different approaches and discovered that foo === undefinedis faster and therefore decided it's the way to go. [UPDATE: as noted in the comments, the comparison with undefinedis also slightly shorter, which could be a consideration.]However, the gain in practical situations will be utterly insignificant: this check will never, ever be any kind of bottleneck, and what you lose is significant: evaluating a property of a host object for comparison can throw an error whereas a typeofcheck never will.

我想 jQuery 推荐这两种不同方法的原因是它们undefined在 jQuery 代码所在的函数中定义了自己的变量,因此在该函数中undefined是安全的,不会被外部篡改。我还想像某个地方的某个人对这两种不同的方法进行了基准测试,发现它foo === undefined更快,因此决定这是要走的路。[更新:如评论中所述,与 的比较undefined也略短,这可能是一个考虑因素。]然而,在实际情况下的收益将完全微不足道:此检查永远不会成为任何类型的瓶颈,以及什么你失去的是重要的:评估一个宿主对象的属性进行比较可能会抛出一个错误,而一个typeof检查永远不会。

For example, the following is used in IE for parsing XML:

例如,在 IE 中使用以下内容来解析 XML:

var x = new ActiveXObject("Microsoft.XMLDOM");

To check whether it has a loadXMLmethod safely:

要检查它是否具有loadXML安全的方法:

typeof x.loadXML === "undefined"; // Returns false

On the other hand:

另一方面:

x.loadXML === undefined; // Throws an error

UPDATE

更新

Another advantage of the typeofcheck that I forgot to mention was that it also works with undeclared variables, which the foo === undefinedcheck does not, and in fact throws a ReferenceError. Thanks to @LinusKleen for reminding me. For example:

typeof我忘记提及的检查的另一个优点是它也适用于未声明的变量,foo === undefined检查不这样做,并且实际上抛出一个ReferenceError. 感谢@LinusKleen 提醒我。例如:

typeof someUndeclaredVariable; // "undefined"
someUndeclaredVariable === undefined; // throws a ReferenceError

Bottom line: always use the typeofcheck.

底线:始终使用typeof支票。

回答by Jakob

Yet another reason for using the typeof-variant: undefinedcan be redefined.

使用 typeof-variant 的另一个原因:undefined可以重新定义。

undefined = "foo";
var variable = "foo";
if (variable === undefined)
  console.log("eh, what?!");

The result of typeof variablecannot.

结果typeof variable不能。

Update: note that this is not the case in ES5 there the global undefinedis a non-configurable, non-writable property:

更新:请注意,在 ES5 中情况并非如此,全局undefined是不可配置、不可写的属性:

15.1.1 Value Properties of the Global Object
[...]
15.1.1.3 undefined
The value of undefinedis undefined (see 8.1). This property has the attributes
{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

15.1.1 全局对象的值属性
[...]
15.1.1.3 undefined
的值undefined未定义(见 8.1)。此属性具有属性
{ [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }。

But it still can be shadowed by a local variable:

但它仍然可以被局部变量遮蔽:

(function() {
  var undefined = "foo";
  var variable = "foo";
  if (variable === undefined)
    console.log("eh, what?!");  
})()

or parameter:

或参数:

(function(undefined) {
  var variable = "foo";
  if (variable === undefined)
    console.log("eh, what?!");  
})("foo")

回答by Struppi

Because undefinedis not always declared, but jQuery declares undefinedin its main function. So they use the safe undefinedvalue internally, but outside, they use the typeofstyle to be safe.

因为undefined并不总是声明的,但 jQueryundefined在其 main 函数中声明。所以他们在undefined内部使用安全值,但在外部,他们使用typeof样式是安全的。

回答by RiZKiT

Who is interested in the performance gain of variable === undefined, may take a look here, but it seems to be a chrome optimization only.

谁对 的性能增益感兴趣variable === undefined,可以看看这里,但它似乎只是一个 chrome 优化。

回答by CodingYoshi

For local variables, checking with localVar === undefinedwill work because they must have been defined somewhere within the local scope or they will not be considered local.

对于局部变量,检查 withlocalVar === undefined将起作用,因为它们必须已在局部范围内的某处定义,否则它们将不被视为局部变量。

For variables which are not local and not defined anywhere, the check someVar === undefinedwill throw exception: Uncaught ReferenceError: j is not defined

对于非局部且未在任何地方定义的变量,检查someVar === undefined将抛出异常:Uncaught ReferenceError: j is not defined

Here is some code which will clarify what I am saying above. Please pay attention to inline comments for further clarity.

这里有一些代码可以澄清我上面所说的内容。请注意内嵌注释以进一步明确

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\'].');
};

If we call the above code like this:

如果我们这样调用上面的代码:

f();

The output would be this:

输出将是这样的:

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.

If we call the above code like these (with any value actually):

如果我们像这样调用上面的代码(实际上是任何值):

f(null); 
f(1);

The output will be:

输出将是:

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.


When you do the check like this: typeof x === 'undefined', you are essentially asking this: Please check if the variable xexists (has been defined) somewhere in the source code.(more or less). If you know C# or Java, this type of check is never done because if it does not exist, it will not compile.

当您像这样进行检查时:typeof x === 'undefined',您实际上是在问:请检查x源代码中某处是否存在(已定义)变量。(或多或少)。如果您了解 C# 或 Java,则永远不会进行此类检查,因为如果它不存在,则不会编译。

<== Fiddle Me ==>

<== 摆弄我 ==>

回答by Willem van der Veen

Summary:

概括:

When at global scope we actually want to return true if the variable is not declared or has the value undefined:

在全局范围内,如果变量未声明或具有值,我们实际上希望返回 true undefined

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);

Because in global scope we are not 100% sure if a variable is declared this might give us a referenceError. When we use the typeofoperator on the unknown variable we are not getting this issue when the variable is not declared:

因为在全局范围内,我们不能 100% 确定是否声明了一个变量,这可能会给我们一个引用错误。当我们typeof在未知变量上使用运算符时,我们不会在未声明变量时遇到此问题:

var globalVar1;

console.log(typeof globalVar1 === 'undefined');
console.log(typeof globalVar2 === 'undefined');

This is due to the fact that the typeofoperator returns the string undefinedwhen a variable is not declared or currently hold the value undefinedwhich is exactly what we want.

这是因为当变量未声明或当前保存的值正是我们想要的时,typeof运算符返回字符串。undefinedundefined



  • With local variables we don't have this problem because we know beforehand that this variable will exist. We can simply look in the respective function if the variable is present.
  • With object properties we don't have this problem because when we try to lookup an object property which does not exist we also get the value undefined
  • 对于局部变量,我们没有这个问题,因为我们事先知道这个变量会存在。如果变量存在,我们可以简单地查看相应的函数。
  • 对于对象属性,我们没有这个问题,因为当我们尝试查找不存在的对象属性时,我们也会得到值 undefined

var obj = {};

console.log(obj.myProp === undefined);

回答by Eduard Popov

typeof a === 'undefined'is faster then a === 'undefined'by about 2 times on node v6.9.1.

typeof a === 'undefined'a === 'undefined'在节点 v6.9.1 上快了大约 2 倍。