JavaScriptオブジェクトの要素数


103

JavaScriptオブジェクトの要素の数を(どこかから)取得する方法はありますか?(つまり、一定時間の複雑さ)。

その情報を取得するプロパティまたはメソッドが見つかりません。これまでのところ、コレクション全体を反復処理することしか考えられませんが、それは線形時間です。
オブジェクトのサイズに直接アクセスできないのは奇妙なことです。

編集:
私はObjectオブジェクトについて話している(一般的なオブジェクトではない):

var obj = new Object ;

5
すでにここに答えstackoverflow.com/questions/126100/... Object.keys(OBJ).LENGTH
スパッツ

回答:


155

JS実装はそのような値を内部的に追跡しているかもしれませんが、それを取得する標準的な方法はありません。

これまで、MozillaのJavascriptバリアントは非標準のを__count__公開していましたが、バージョン1.8.5で削除されました。

クロスブラウザのスクリプトのためには、明示的にプロパティを反復処理し、チェックして立ち往生していますhasOwnProperty()

function countProperties(obj) {
    var count = 0;

    for(var prop in obj) {
        if(obj.hasOwnProperty(prop))
            ++count;
    }

    return count;
}

ECMAScript 5対応の実装の場合、これは(Kudos to Avi Flax)としても記述できます。

function countProperties(obj) {
    return Object.keys(obj).length;
}

列挙できないプロパティ(たとえば、配列length)も見逃してしまうことに注意してください。

jQuery、Prototype、Mootools、$ whatever-the-newest-hypeなどのフレームワークを使用している場合は、独自のコレクションAPIが付属しているかどうかを確認します。これは、ネイティブJSオブジェクトを使用するよりも問題の解決策として適しています。


11
私はいつもhasOwnPropertyを忘れています。.NETの土地にいる時間が長すぎると言います。+1
アナカタ09/06/05

2
jQueryは、クエリから取得したコレクションにオブジェクトを使用し、その値を長さプロパティで公開します。
Nosredna

6
Firefox4 __count__が廃止されました:(
Timo Huovinen、2011

1
for forなしでこれを行う方法はありますか?私は同じタイプのバインドにいますが、可能であればJSLintを渡すようにしたいと思います。
街灯2013年

1
なぜ必要なのhasOwnProperty()ですか?
スイス

99

ES5互換の環境でこれを行うには

Object.keys(obj).length

ここからのブラウザーサポート)
(Object.keysのドキュメントはこちら、非ECMA5ブラウザーに追加できるメソッドが含まれます)


2
これは、この答えに当てはまる正しい質問ではありません。これで、オブジェクトのすべてのキーを取得し、それらを新しく作成された配列に配置して、その新しい配列からlengthプロパティを取得します。
GetFree 2013年

11
プログラム的には効率的ではないかもしれませんが、開発者にとっては最も効率的です。
スーパーミナミ2016年

9

ビルドですでにjQueryを使用している場合は、次のようにします。

$(yourObject).length

オブジェクトに対してはうまく機能し、依存関係としてすでにjQueryを使用していました。


5
奇妙なことに...これは私にはうまくいきません。私は常に1を受け取ります。ZelkiNの答えは私のために働きます。
マイクげっ歯類2017年

3
このコードは常に1を返します。オブジェクトは1つだけです。それはその中の要素を数えていません
BeRocket 2018年

5
function count(){
    var c= 0;
    for(var p in this) if(this.hasOwnProperty(p))++c;
    return c;
}

var O={a: 1, b: 2, c: 3};

count.call(O);

2

申し訳ありませんが、アレイに切り替えない限り、これを確実に行う方法はありません。これは正直、しない奇妙に思える-それは配列が可算であることを私にはかなりまっすぐ進むようだだし、オブジェクトではありません。

おそらくあなたが得る最も近いものはこのようなものです

// Monkey patching on purpose to make a point
Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this ) i++;
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 3

しかし、これは問題、または少なくとも質問を作成します。_length関数自体を含む、すべてのユーザー作成プロパティがカウントされます!この単純な例では、通常の関数を使用するだけでそれを回避できますが、これは、他のスクリプトがこれを実行するのを停止できるという意味ではありません。それで、あなたは何をしますか?関数のプロパティを無視しますか?

Object.prototype.length = function()
{
  var i = 0;
  for ( var p in this )
  {
      if ( 'function' == typeof this[p] ) continue;
      i++;
  }
  return i;
}

alert( {foo:"bar", bar: "baz"}.length() ); // alerts 2

結局のところ、オブジェクトを数えることができるようにするという考えを捨て、自分がしていることを何でも行う別の方法を考えるべきだと思います。


8
危険がロビンソンになります!オブジェクトに対してプロトしないでください!すべてがObjectから派生したものであり、かなりの量のJS作業を行っている場合は、このようにクライアントの処理を無効にします。
アナカタ09/06/05

5
ええと...私がコメントで書いた部分「あなたがポイントを作るために意図的にパッチを当てている」を読んでいませんでした-さて、私は人々がそれについて少しフリップしないように意図的にそれをしました。その上、私がモンキーパッチを提唱していなくても、パフォーマンスの問題が発生すると考えられる場合、JavaScriptでのプロトタイプチェーンの動作を誤解しています。video.yahoo.com/ watch / 111585/1027823
Peter Bailey

それで、これはするべきかしないべきか?
OscarRyz 2012年

「Javascript:The Good Parts」では、「create()」メソッドを使用してオブジェクトのプロトタイプを作成しています。これはJavascriptの最も信頼できる本だと思います。
Chris Dutrow、2012年

1

数/長さ/次元の概念はオブジェクトにとって実際には意味がなく、それを必要とすることは本当に配列を私に望んでいることを示唆しています。

編集:これにはO(1)が必要であることを指摘しました。私の知る限りでは、そのような方法は存在しません。


彼は自分自身を反復することを提案しました、これはこの解決策です。彼はこれを達成するためにO(1)の方法が必要でした...
トーマス・ハンセン

あなたはまったく正しい。本当に質問をもっと徹底的に読むべきです。
アナカタ09年

実際、オブジェクトはJSにあるマップに最も近いものです。マップには長さがあります。
クリスティアンヴラビー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.