我一直以为只有
我有以下代码:
后来,我使用这个
这会导致代码不能正常工作,因为
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;
}
}
}
这会导致代码不能正常工作,因为
i
是一个整数索引,在obj
View
上并没有被实际定义。准确来说,在上面的代码中,obj[0]
是undefined
,而obj.length === +obj.length
为true
,obj.length
是1
。到底发生了什么?
附录
Underscore的首席维护者在https://github.com/documentcloud/underscore/pull/510上表示:
附录2 意识到我不能传递一个函数对象给简单地将每个拒绝函数对象化并不真正有所帮助。我们已经做出了明智的决定,使用数字长度属性来检测类似于数组的对象。
相反,不要将函数对象传递给
each
。
_.each
,我可以像这样“强制转换”为一个常规对象:var regular_obj = _.extend({}, View);
_.each
被调用在哪里? - Matt Ball_.contains
之后,_.contains
使用_.any
,而_.any
又使用了_.each
。 - Dmitry Minkovsky