Javascript (obj.length===+;obj.length)的比较结果是什么?

Javascript (obj.length===+;obj.length)的比较结果是什么?,javascript,underscore.js,Javascript,Underscore.js,我一直在阅读源代码,并注意到中的比较。each(): 我知道+在变量将其转换为数字/整数之前。所以在这个原因上, [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案例,我可以看出,这种比较可能是为了区分数组和对象,

我一直在阅读源代码,并注意到
中的比较。each():

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

[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案例,我可以看出,这种比较可能是为了区分数组和对象,就像它在else案例中使用的那样:

  for (var key in obj) { ...

我看不出有任何理由使用这种比较。有人能解释一下吗?

基本上,这是一种测试
长度属性的类型是
Number
,而不使用
typeof
NaN
的方法。因此,实际上:

if (typeof obj.length === "number" && !isNaN(obj.length))
比较
n===+n
只对一个数字有效,因为
==
测试类型和值,而
+n
将创建一个
数字
(正如您所发现的,可能是数字
NaN
)。因为
NaN===NaN
为false,所以它也会删除这些内容

因此,这是一种检测方法,根据一个定义(“有一个数值
长度
,不是
NaN
”),要迭代的对象是否类似数组。JavaScript和浏览器世界中有几种类似数组的东西,比如
参数
伪数组和DOM的
节点列表
s


愚蠢的性能比较:

  • +
    类型的对比
    无需担心
    NaN
  • +
    类型的对比
    isNaN
    :|
结果是:如果没有
NaN
特性,
typeof
的速度更快(当类型错误时明显如此)。对于
NaN
特性,
+
在结果为
true
时更快,在结果为false时更快,因为它是
NaN
,而在结果为
false
时更慢(明显如此),因为它是错误的类型。(当然,歌剧与以往不同。)


这在现实世界中并不重要(参见上面的“傻瓜”)

我认为这是区分
对象
实例与
数组
实例或“数组”对象(如
参数
)的一种快速方法


如果
对象
实例包含
长度
属性,则该属性将中断。比如
{a:1,length:1}
,或者作为
[].push.call({},'a value')
(其结果是:
{0:'a value',length:1}
)。正如上下文中的

所示,我认为它试图弄清楚
obj
是否是一个数组,因为在一个循环上迭代需要一个连续的
循环,而不是
循环中的
-

运算符返回对象的数字表示形式。因为您的代码+obj.length意味着它返回一个数字引用。。。。。当它是一个数组时,您将获得+obj.length值作为数字,但在var obj={a:1,b:2,c:3}的情况下,它不返回长度;因为它不是数组…当您使用[1,2,3,{a:[4,5,6]}]时,其返回的长度为4,因为对象在数组中…

NaN!=NaN
是真的这里还有一些有趣的答案:我想如果我有这样的东西就会失败:
var ob={a:5,length:3}
@Francodi谢谢!没有发现:)或类似数组的对象。@Felix:是的,已将其添加到回答中感谢提供参数和节点列表等示例!更准确地说,它测试
length
是否是一个数字,而不是NaN。他们也可以使用
isFinite
。@thg435:很好。但是
isFinite
对于
Infinity
也是
false
。:-)@thg435:当然,(
isFinite
being
false
for
Infinity
)可能是一件好事:对于他们当前的检查,假设他们使用
for(i=0;i
,他们将永远循环。
if (typeof obj.length === "number" && !isNaN(obj.length))