4

私は、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でありtrueobj.lengthis1です。何が起きてる?

補遺

Underscoreのチーフメンテナーは、https: //github.com/documentcloud/underscore/pull/510で次のように述べています。

それぞれのreject関数オブジェクトを作成するだけでは、実際には役に立ちません。配列のようなオブジェクトを検出するために数値の長さプロパティを使用することを意識的に決定しました。

代わりに、関数オブジェクトをに渡さないでくださいeach

補遺2

関数オブジェクトをに渡すことができなかった_.eachので、次のように通常のオブジェクトに「キャスト」できることに気づきました。

var regular_obj = _.extend({}, View);
4

2 に答える 2

5

ここでの問題はunderscore.js、と同様jqueryに、どちらも.lengthプロパティを関数のフラグとして使用することeachです。プロパティが存在する場合length、関数は、渡された引数が通常のforループで反復可能であると想定します。このロジックの背後にある理由は、プロパティが定義されたときに、引数を順番lengthに繰り返すことができるという期待があるためです。これが、forループが使用される理由です。

誤用の結果lengthは、本質的に、意図しない結果が生じる名前の衝突です。または、などlengthの別の同義語に変更することをお勧めします。sizecapacitytotalViews


編集

使用する他の選択肢がなく、機能を維持しながら長さを確保する必要がある_.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場合に使用しますが、 。lengthtypeof(yourObject[0]) == "undefined"

于 2013-03-18T23:35:10.463 に答える
5

JavaScriptのどのオブジェクトに.lengthプロパティがありますか?

非常にトートロジー的な定義によると、lengthプロパティを持つすべてのオブジェクト。

これにはたまたま関数が含まれています。

lengthは関数オブジェクトのプロパティであり、関数が期待する引数の数、つまり仮パラメータの数を示します。

:があるため、これも配列に似ていますlength

var foo = {
    bar: true,
    baz: 'quux',
    length: 42
}
于 2013-03-18T23:18:52.343 に答える