我一直认为只有Array
个对象具有.length
属性。但是,我再次看到提到“阵列式”的对象。我没有调查过这个,现在看来我对JS中这个话题的无知可能会让我陷入困境。一个很好的例子:
我有以下代码:
var View = function(options) {
// code
};
_.extend(View, Backbone.Events, {
make_children: function(parent) {
// code
}
});
稍后,我将此View
Function
与Underscore的_.each
一起使用,后者决定此函数对象是一个数组,因为它具有.length
属性:
// Code from Underscore.js's `_.each`:
} else if (obj.length === +obj.length) { // This is true
for (var i = 0, l = obj.length; i < l; i++) { // **So, execution goes here**
if (iterator.call(context, obj[i], i, obj) === breaker) return
}
} else {
for (var key in obj) {
if (_.has(obj, key)) { // **Execution does __not__ go here**
if (iterator.call(context, obj[key], key, obj) === breaker) return;
}
}
}
这导致代码不起作用,因为obj[i]
其中i
是整数索引,实际上并未在obj
View
上定义。确切地说,在上面的代码中,obj[0]
是undefined
,而obj.length === +obj.length
是true
而obj.length
是1
。这是怎么回事?
附录
Underscore的首席维护人员在https://github.com/documentcloud/underscore/pull/510上说了以下内容:
简单地制作每个拒绝功能对象并没有多大帮助。我们已经 有意识地决定使用数字长度属性来检测 类似数组的对象。
相反,不要将函数对象传递给
each
。
附录2
意识到由于我无法将函数对象传递给_.each
,我可以将它“强制转换”为常规对象,如下所示:
var regular_obj = _.extend({}, View);
答案 0 :(得分:5)
JavaScript中的哪些对象具有
.length
属性?
通过如此重复的定义,任何具有length
属性的对象。
This happens to include functions.
length
是函数对象的属性,表示函数期望的参数数量,即形式参数的数量。
这也是类似数组的,因为它有一个length
:
var foo = {
bar: true,
baz: 'quux',
length: 42
}
答案 1 :(得分:5)
此处的问题是underscore.js
与jquery
非常相似,都使用.length
属性作为其each
函数中的标记。当length
属性存在时,该函数假定传递的参数可以通过正常的for循环迭代。这个逻辑背后的原因是期望在定义length
属性时,可以按顺序迭代参数 ,这就是使用for循环的原因。
误用length
的结果本质上是名称冲突,其中存在意外结果。我建议将length
更改为另一个同义词,例如size
或capacity
或totalViews
等。
修改
如果没有其他选择供您使用,并且您必须保留其中的长度,同时仍然保留_.each
的功能,那么您可以稍微破解它。此插件适用于下划线版本1.4.3的缩小版本
var s = Array.prototype.ForEach;
var r = {};
var myEach = function (n,t,e){if(null!=n)if(s&&n.forEach===s)n.forEach(t,e);else if(n.length===+n.length&&typeof(n[0])!="undefined"){for(var u=0,i=n.length;i>u;u++)if(t.call(e,n[u],u,n)===r)return}else for(var a in n)if(_.has(n,a)&&t.call(e,n[a],a,n)===r)return};
_.each=myEach;
以下是演示:http://jsfiddle.net/Xa5qq/
基本上,当forEach
属性存在但length
时,它会使用typeof(yourObject[0]) == "undefined"
。