1822

オブジェクトのキー/プロパティの数を数える最も速い方法は何ですか?オブジェクトを反復処理せずにこれを行うことは可能ですか?つまり、何もせずに:

var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) ++count;

(Firefoxは魔法の__count__プロパティを提供しましたが、これはバージョン4のあたりで削除されました。)

4

20 に答える 20

2925

Node.js、Chrome、Internet Explorer 9以降、Firefox 4 以降、Safari 5以降などのES5互換環境でこれを行うには:

Object.keys(obj).length
于 2011-02-03T17:47:20.957 に答える
160

次のコードを使用できます。

if (!Object.keys) {
    Object.keys = function (obj) {
        var keys = [],
            k;
        for (k in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, k)) {
                keys.push(k);
            }
        }
        return keys;
    };
}

次に、これを古いブラウザでも使用できます。

var len = Object.keys(obj).length;
于 2011-04-15T10:48:18.177 に答える
140

Underscore.jsを使用している場合は、_.sizeを使用できます( thanks douwe ) :

_.size(obj)

または、一部の人にとってはより明確な_.keysを使用することもできます。

_.keys(obj).length

Underscore.js を強くお勧めします。多くの基本的なことを行うためのタイトなライブラリです。可能な限り、それらはECMAScript 5に一致し、ネイティブ実装に従います。

それ以外の場合は、 Avi Flax の回答をサポートします。ECMAScript 5 以外のブラウザーに追加できる keys() メソッドを含むMDCドキュメントへのリンクを追加するように編集しました。

于 2011-05-16T15:24:17.140 に答える
92

標準の Object 実装 ( ES5.1 Object Internal Properties and Methods ) では、 がそのキー/プロパティの数を追跡する必要がないため、そのキーを明示的または暗黙的に反復せずにObjectのサイズを決定する標準的な方法はありません。Object

したがって、最も一般的に使用される代替手段は次のとおりです。

1. ECMAScript の Object.keys()

Object.keys(obj).length;キーを内部的に反復処理して一時配列を計算し、その長さを返します。

  • 長所- 読みやすく、きれいな構文。ネイティブ サポートが利用できない場合、shim を除いて、ライブラリやカスタム コードは必要ありません
  • 短所- 配列の作成によるメモリ オーバーヘッド。

2. ライブラリベースのソリューション

このトピックの他の場所にある多くのライブラリベースの例は、ライブラリのコンテキストで役立つイディオムです。ただし、パフォーマンスの観点からは、これらのライブラリ メソッドはすべて for ループまたは ES5 Object.keys(ネイティブまたはシム) のいずれかを実際にカプセル化するため、完全なライブラリなしコードと比較して得られるものは何もありません。

3. for ループの最適化

このような for ループの最も遅い部分.hasOwnProperty()は、関数呼び出しのオーバーヘッドのため、一般に呼び出しです。したがって、JSON オブジェクトのエントリ数だけが必要な.hasOwnProperty()場合は、コードが拡張されていない、または拡張されないことがわかっている場合は、呼び出しを スキップしますObject.prototype

kそれ以外の場合は、ローカル ( ) を作成し、後置の代わりにvar k前置インクリメント演算子 () を使用することで、コードをわずかに最適化できます。++count

var count = 0;
for (var k in myobj) if (myobj.hasOwnProperty(k)) ++count;

hasOwnProperty別のアイデアは、メソッドのキャッシュに依存しています。

var hasOwn = Object.prototype.hasOwnProperty;
var count = 0;
for (var k in myobj) if (hasOwn.call(myobj, k)) ++count;

特定の環境でこれが高速かどうかは、ベンチマークの問題です。いずれにせよ、非常に限られたパフォーマンスの向上が期待できます。

于 2013-05-26T21:39:23.713 に答える
34

実際にパフォーマンスの問題が発生している場合は、オブジェクトとの間でプロパティを追加/削除する呼び出しを、適切な名前の(サイズ?)プロパティもインクリメント/デクリメントする関数でラップすることをお勧めします。

プロパティの初期数を一度計算して、そこから先に進むだけです。実際のパフォーマンスの問題がない場合は、気にしないでください。コードのそのビットを関数でラップして、それでgetNumberOfProperties(object)完了します。

于 2008-09-24T09:11:22.273 に答える
18

Avi Flax が述べたように、

Object.keys(obj).length

オブジェクトのすべての列挙可能なプロパティに対してトリックを実行しますが、列挙不可能なプロパティも含めるには、代わりにObject.getOwnPropertyNames. 違いは次のとおりです。

var myObject = new Object();

Object.defineProperty(myObject, "nonEnumerableProp", {
  enumerable: false
});
Object.defineProperty(myObject, "enumerableProp", {
  enumerable: true
});

console.log(Object.getOwnPropertyNames(myObject).length); //outputs 2
console.log(Object.keys(myObject).length); //outputs 1

console.log(myObject.hasOwnProperty("nonEnumerableProp")); //outputs true
console.log(myObject.hasOwnProperty("enumerableProp")); //outputs true

console.log("nonEnumerableProp" in myObject); //outputs true
console.log("enumerableProp" in myObject); //outputs true

ここで述べたように、これは と同じブラウザ サポートを備えていObject.keysます。

ただし、ほとんどの場合、これらのタイプの操作に数値不可を含めたくない場合がありますが、違いを知っておくことは常に良いことです;)

于 2013-01-17T11:15:44.757 に答える
14

私はこれを行う方法を知りません。ただし、反復を最小限に抑えるために、存在を確認し、存在__count__しない場合(つまり、Firefoxではない場合)、オブジェクトを反復して、後で使用するために定義することができます。例:

if (myobj.__count__ === undefined) {
  myobj.__count__ = ...
}

このように、サポートしているブラウザ__count__はそれを使用し、反復は使用しないブラウザに対してのみ実行されます。カウントが変更されてこれを実行できない場合は、いつでも関数にすることができます。

if (myobj.__count__ === undefined) {
  myobj.__count__ = function() { return ... }
  myobj.__count__.toString = function() { return this(); }
}

このようにして、myobjを参照するときはいつでも。__count__関数が起動して再計算します。

于 2008-09-24T09:13:13.343 に答える
8

Object.defineProperty()から:

Object.defineProperty(obj, prop, descriptor)

すべてのオブジェクトに追加できます。

Object.defineProperty(Object.prototype, "length", {
    enumerable: false,
    get: function() {
        return Object.keys(this).length;
    }
});

または単一のオブジェクト:

var myObj = {};
Object.defineProperty(myObj, "length", {
    enumerable: false,
    get: function() {
        return Object.keys(this).length;
    }
});

例:

var myObj = {};
myObj.name  = "John Doe";
myObj.email = "leaked@example.com";
myObj.length; // Output: 2

そのように追加すると、for..inループでは表示されません:

for(var i in myObj) {
    console.log(i + ": " + myObj[i]);
}

出力:

name: John Doe
email: leaked@example.com

注: Internet Explorer 9より前のブラウザーでは機能しません。

于 2015-08-21T03:37:26.703 に答える
7

プロジェクトに Underscore.js が含まれている場合は、次のことができます。

_({a:'', b:''}).size() // => 2

または機能的なスタイル:

_.size({a:'', b:''}) // => 2
于 2012-01-04T09:04:06.883 に答える
5

この問題をどのように解決したかは、オブジェクトに格納されているアイテムの数の記録を保持する基本リストの独自の実装を構築することです。とても簡単です。このようなもの:

function BasicList()
{
   var items = {};
   this.count = 0;

   this.add = function(index, item)
   {
      items[index] = item;
      this.count++;
   }

   this.remove = function (index)
   {
      delete items[index];
      this.count--;
   }

   this.get = function(index)
   {
      if (undefined === index)
        return items;
      else
        return items[index];
   }
}
于 2011-06-28T10:04:16.987 に答える
3

プロジェクトにExt JS 4 がある場合は、次のことができます。

Ext.Object.getSize(myobj);

これの利点は、すべての Ext JS 互換ブラウザー ( Internet Explorer 6 - Internet Explorer 8を含む) で動作することです。ただし、他の提案されたソリューションと同様に、実行時間は O(n) よりも優れているとは思いません。

于 2012-04-12T07:40:14.127 に答える
1

OP は、オブジェクトが nodeList であるかどうかを指定しませんでした。そうであれば、lengthメソッドを直接使用できます。例:

buttons = document.querySelectorAll('[id=button)) {
console.log('Found ' + buttons.length + ' on the screen');
于 2019-06-22T05:21:07.110 に答える
0

前の回答の jQuery が機能しない場合は、試してください

$(Object.Item).length
于 2012-09-02T01:32:01.147 に答える
-3

私はこれが可能だとは思いません(少なくともいくつかの内部を使用せずに)。そして、これを最適化することによってあなたが多くを得るとは思わない。

于 2008-09-24T09:05:38.777 に答える