variables===未定义与typeofvariables===“undefined”

jQuery Core Style Guidelines提供了两种不同的方法来检查variables是否被定义。

  • 全局variables: typeof variable === "undefined"
  • 局部variables: variable === undefined
  • 属性: object.prop === undefined

为什么jQuery对全局variables使用一种方法,对于局部和属性使用另一种方法?

对于未声明的variables, typeof foo将返回string字面量"undefined" ,而身份检查foo === undefined会触发错误“foo未定义”

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

我坚持使用typeof foo === "undefined"无处不在。 那永远不会出错。

我想jQuery推荐两种不同的方法的原因是,他们在jQuery代码所在的函数中定义了自己的undefinedvariables,所以在这个函数中, undefined是安全的,不会被外部篡改。 我也想象某个地方的人对这两种不同的方法进行了基准testing,发现foo === undefined的速度更快,因此决定这是一条路。 [更新:正如评论中指出的那样,与undefined的比较也略短,这可能是一个考虑。]然而,在实际情况下的收益将是微不足道的:这种检查永远不会是任何一种瓶颈,你失去了什么是显着的:评估一个宿主对象的属性进行比较可以抛出一个错误,而types检查永远不会。

例如,以下内容在IE中用于parsingXML:

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

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

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

另一方面:

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

UPDATE

我忘记提及的typeof检查的另一个优点是它也适用于未声明的variables,其中foo === undefined检查没有,并且实际上抛出一个ReferenceError 。 感谢@LinusKleen提醒我。 例如:

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

底线:总是使用typeof检查。

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

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

typeof variable的结果不能。

更新 :请注意,这不是ES5中的情况。

因为undefined并不总是被声明的,但是jQuery在其主函数中声明了undefined 。 所以他们在内部使用安全的undefined值,但在外面,他们使用typeof风格是安全的。

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

对于本地variables,使用localVar === undefined检查是可行的,因为它们必须在本地范围内的某处定义,否则将不被视为本地。

对于不是本地的,没有在任何地方定义的variables,检查someVar === undefined将会抛出exception: Uncaught ReferenceError:j未定义

这里是一些代码,将澄清我上面说的。 请注意内联评论以进一步清晰

 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' ,你基本上是这样问的: 请检查variablesx存在(已定义)在源代码中的某处。 (或多或less)。 如果你知道C#或Java,这种types的检查永远不会完成,因为如果它不存在,它将不会被编译。

<== Fiddle Me ==>

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