私は、Arrayオブジェクトだけが.lengthプロパティを持っているという印象を受けてきました。しかし、繰り返しになりますが、「配列のような」オブジェクトについての言及も見ました。私はこれを調べていませんが、JSでこのトピックを知らないことが、私を尻に食い込ませているようです。適例:
私は次のコードを持っています:
var View = function(options) {
// code
};
_.extend(View, Backbone.Events, {
make_children: function(parent) {
// code
}
});
後で、これView Functionをアンダースコアで使用します。アンダースコアは、次のプロパティ_.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]はundefinedwhileobj.length === +obj.lengthでありtrue、obj.lengthis1です。何が起きてる?
補遺
Underscoreのチーフメンテナーは、https: //github.com/documentcloud/underscore/pull/510で次のように述べています。
それぞれのreject関数オブジェクトを作成するだけでは、実際には役に立ちません。配列のようなオブジェクトを検出するために数値の長さプロパティを使用することを意識的に決定しました。
代わりに、関数オブジェクトをに渡さないでください
each。
補遺2
関数オブジェクトをに渡すことができなかった_.eachので、次のように通常のオブジェクトに「キャスト」できることに気づきました。
var regular_obj = _.extend({}, View);