(obj.length === + obj.length)比较什么?

时间:2013-07-01 07:32:12

标签: javascript underscore.js

我一直在阅读underscore.js源代码,并注意到_.each():

中的这种比较
(obj.length === +obj.length)

我知道在变量转换为数字/整数之前+。所以在这个原因

[1,2,3].length === +[1,2,3].length

是真的。如果我传入一个对象:

var obj = {a: 1, b: 2, c: 3};

+obj.length生成 NaN

在最后一种情况下,我有

[1,2,3, {a: [4,5,6]}].length

这是4.将它投射到一个数字..仍然是4.

else case 决定,我可以看到这种比较可能是为了区分数组和对象,就像它使用的其他情况一样:

  for (var key in obj) { ...

我没有看到任何使用这种比较的理由。谁能解释一下?

4 个答案:

答案 0 :(得分:6)

基本上,这是一种测试length属性类型为Number的方法,而不使用typeof ,但该数字不是{{1} }。所以实际上:

NaN

比较if (typeof obj.length === "number" && !isNaN(obj.length)) 仅适用于某个数字,因为n === +n会测试类型和值,而===会创建+n(可能就像您找到的那样) ,数字Number)。而且因为NaN是假的,所以它也会将它们除掉。

所以这是一种检测方法,根据一个定义(“有一个不是NaN === NaN的数字length”),要迭代的对象是否为array- < / em>的。 JavaScript和浏览器世界中有几个类似于数组的东西,例如NaN伪数组和DOM的arguments


愚蠢的表现比较:

Upshot:没有isNaN方面,NaN更快(当类型错误时显然更快)。使用typeof方面,NaN在结果为+时会更快,而当它为true时会更慢,而在结果为NaN时会更慢(显着)是false,因为它是错误的类型。 (歌剧当然一如既往地不同。)

并不是说它在现实世界中很重要(见上文“愚蠢”)。

答案 1 :(得分:1)

我认为这是区分Object实例与Array实例或' Arrayish '对象(如arguments)的快速方法。

如果Object实例包含length属性,它将会中断。与{a:1, length: 1}一样,或[].push.call({},'a value')的结果(结果如下:{0:'a value',length: 1})。如this jsFiddle

中所示

答案 2 :(得分:1)

从上下文来看,我认为它试图弄清楚obj是否是一个数组,因为迭代一个数组需要一个顺序for循环而不是for - inhttps://stackoverflow.com/a/3010848/367273

答案 3 :(得分:0)

+运算符返回对象的数字表示。因为你的代码+ obj.length意味着它返回一个数字引用.... this。你得到一个数组时,+ obj.length值为Number,但如果var obj = {a:1,b:2,c:3}则不返回长度;因为它不是一个数组......当你使用[1,2,3,{a:[4,5,6]}]。长度时它返回4作为对象在数组中......