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代码所在的函数中定义了自己的undefined
variables,所以在这个函数中, 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倍。