变量===未定义变量=== "未定义"

时间:2022-11-05 20:46:08

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

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

  • Global Variables: typeof variable === "undefined"
  • 全局变量:typeof变量== "未定义"
  • Local Variables: variable === undefined
  • 局部变量:变量==未定义。
  • Properties: object.prop === undefined
  • 属性:对象。支持= = =定义

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

为什么jQuery使用一种方法来处理全局变量,而另一种方法用于本地和属性?

7 个解决方案

#1


259  

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

对于未声明的变量,foo类型将返回字符串字面“未定义”,而身份检查foo ===未定义将触发错误“foo没有定义”。

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

对于局部变量(您知道是在某个地方声明的),不会出现这样的错误,因此进行身份检查。

#2


95  

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

我将坚持使用typeof foo == "undefined" everywhere。这永远不会出错。

I imagine the reason why jQuery recommends the two different methods is that they define their own undefined variable within the function that jQuery code lives in, so within that function undefined is safe from tampering from outside. I would also imagine that someone somewhere has benchmarked the two different approaches and discovered that foo === undefined is faster and therefore decided it's the way to go. [UPDATE: as noted in the comments, the comparison with undefined is 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 typeof check never will.

我想,jQuery之所以推荐这两种不同的方法,是因为它们在jQuery代码所处的函数中定义了自己的未定义变量,所以在未定义的函数中,从外部篡改是安全的。我还可以想象,某个地方的某个人对这两种不同的方法进行了基准测试,并发现foo ===未定义的速度更快,因此决定这是一种方法。[更新:在评论中指出,与未定义的比较也稍短,这可能是一个考虑因素。然而,在实际情况中获得的收益将是完全无关紧要的:这种检查永远不会成为任何类型的瓶颈,而您所失去的是显著的:对一个主机对象的属性进行评估可以抛出一个错误,而一种类型的检查永远不会出错。

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 loadXML method safely:

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

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

On the other hand:

另一方面:

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

UPDATE

更新

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

我忘记提到的类型检查的另一个优点是,它也适用于未声明的变量,其中foo ==未定义的检查没有,实际上抛出了一个引用错误。感谢@LinusKleen提醒我。例如:

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

Bottom line: always use the typeof check.

底线:总是使用类型检查。

#3


22  

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

使用这种类型的另一个原因是:未定义的可以重新定义。

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

The result of typeof variable cannot.

类型变量的结果不能。

Update: note that this is not the case in ES5.

更新:请注意,在ES5中并非如此。

#4


4  

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

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

#5


4  

Because undefined is not always declared, but jQuery declares undefined in its main function. So they use the safe undefined value internally, but outside, they use the typeof style to be safe.

因为未定义的并不总是被声明,但是jQuery在其主要函数中声明未定义。因此,他们在内部使用安全的未定义值,但在外部,他们使用类型的样式是安全的。

#6


0  

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

对于局部变量,检查localVar ===未定义的将会起作用,因为它们必须在本地范围内定义,否则就不会被认为是本地的。

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

对于非本地且未定义的变量,检查someVar ==未定义的将抛出异常:未捕获的ReferenceError: j未定义。

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 x exists (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 ==>

< = =小提琴我= = >

#7


-1  

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

在节点v6.9.1上,a == '未定义'的类型会更快,然后a = ' = '未定义'。

#1


259  

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

对于未声明的变量,foo类型将返回字符串字面“未定义”,而身份检查foo ===未定义将触发错误“foo没有定义”。

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

对于局部变量(您知道是在某个地方声明的),不会出现这样的错误,因此进行身份检查。

#2


95  

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

我将坚持使用typeof foo == "undefined" everywhere。这永远不会出错。

I imagine the reason why jQuery recommends the two different methods is that they define their own undefined variable within the function that jQuery code lives in, so within that function undefined is safe from tampering from outside. I would also imagine that someone somewhere has benchmarked the two different approaches and discovered that foo === undefined is faster and therefore decided it's the way to go. [UPDATE: as noted in the comments, the comparison with undefined is 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 typeof check never will.

我想,jQuery之所以推荐这两种不同的方法,是因为它们在jQuery代码所处的函数中定义了自己的未定义变量,所以在未定义的函数中,从外部篡改是安全的。我还可以想象,某个地方的某个人对这两种不同的方法进行了基准测试,并发现foo ===未定义的速度更快,因此决定这是一种方法。[更新:在评论中指出,与未定义的比较也稍短,这可能是一个考虑因素。然而,在实际情况中获得的收益将是完全无关紧要的:这种检查永远不会成为任何类型的瓶颈,而您所失去的是显著的:对一个主机对象的属性进行评估可以抛出一个错误,而一种类型的检查永远不会出错。

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 loadXML method safely:

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

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

On the other hand:

另一方面:

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

UPDATE

更新

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

我忘记提到的类型检查的另一个优点是,它也适用于未声明的变量,其中foo ==未定义的检查没有,实际上抛出了一个引用错误。感谢@LinusKleen提醒我。例如:

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

Bottom line: always use the typeof check.

底线:总是使用类型检查。

#3


22  

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

使用这种类型的另一个原因是:未定义的可以重新定义。

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

The result of typeof variable cannot.

类型变量的结果不能。

Update: note that this is not the case in ES5.

更新:请注意,在ES5中并非如此。

#4


4  

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

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

#5


4  

Because undefined is not always declared, but jQuery declares undefined in its main function. So they use the safe undefined value internally, but outside, they use the typeof style to be safe.

因为未定义的并不总是被声明,但是jQuery在其主要函数中声明未定义。因此,他们在内部使用安全的未定义值,但在外部,他们使用类型的样式是安全的。

#6


0  

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

对于局部变量,检查localVar ===未定义的将会起作用,因为它们必须在本地范围内定义,否则就不会被认为是本地的。

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

对于非本地且未定义的变量,检查someVar ==未定义的将抛出异常:未捕获的ReferenceError: j未定义。

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 x exists (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 ==>

< = =小提琴我= = >

#7


-1  

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

在节点v6.9.1上,a == '未定义'的类型会更快,然后a = ' = '未定义'。