javascript - 関数 - オブジェクト プロパティ




どのように効率的にJavaScriptのオブジェクトのキー/プロパティの数をカウントするには? (13)

オブジェクトのキー/プロパティの数を数える最速の方法は何ですか? オブジェクトを反復することなくこれを行うことが可能ですか? すなわち、何もしないで

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

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


Avi Flax https://.com/a/4889658/1047014

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と同じブラウザサポートをObject.keys

しかし、ほとんどの場合、これらの操作に非整数を含めることは望ましくないかもしれませんが、違いを知ることは常に得意です。


Avi Flaxで反復処理するには、Object.keys(obj).lengthは、関数が結び付けられていないオブジェクトに対して正しい

例:

obj = {"lol": "what", owo: "pfft"};
Object.keys(obj).length; // should be 2

arr = [];
obj = {"lol": "what", owo: "pfft"};
obj.omg = function(){
    _.each(obj, function(a){
        arr.push(a);
    });
};
Object.keys(obj).length; // should be 3 because it looks like this 
/* obj === {"lol": "what", owo: "pfft", omg: function(){_.each(obj, function(a){arr.push(a);});}} */

これを避けるための手順:

  1. キーの数を数えたいオブジェクトに関数を入れないでください。

  2. 別々のオブジェクトを使用するか、関数用の新しいオブジェクトを作成します( Object.keys(obj).lengthを使用してファイル内にいくつの関数があるかを数えたいObject.keys(obj).length

私の例ではnodejsの_またはアンダースコアモジュールを使用しました

ドキュメンテーションはUnderscore.jsとgithubのソースとその他のさまざまな情報

最後にlodashの実装https://lodash.com/docs#size

_.size(obj)



Underscore.jsを使用している場合は、 _.size (thanks @Douwe)を使用できます。
_.size(obj)

また、 _.keysを使用することもできます。
_.keys(obj).length

私は非常に基本的なことをたくさん行うためのライブラリ、アンダースコアをお勧めします。 可能な限り、ECMA5と一致し、ネイティブ実装に遅延します。

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


あなたのプロジェクトにUnderscore.jsが含まれている人は、以下のことができます:

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

または機能的スタイル:

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

あなたはこのコードを使うことができます:

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;

上記のjQueryが機能しない場合は、

$(Object.Item).length

上記のように: Object.keys(obj).length

しかし、ES6では実際のMapクラスがあるので、オブジェクトのプロパティを使用する代わりに使用することをおsuggestします。

const map = new Map();
map.set("key", "value");
map.size; // THE fastest way

実際にパフォーマンスの問題に遭遇している場合は、適切な名前のプロパティ(size?)をインクリメント/デクリメントする関数を使用してオブジェクトのプロパティを追加/削除する関数を呼び出すことをおすすめします。

最初のプロパティの数を一度計算してそこから移動するだけで済みます。 実際のパフォーマンスに問題がなければ、気にしないでください。 ちょうどそのコードを関数getNumberOfProperties(object)ラップし、それを使って終了してください。


投稿者: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty : https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/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 = "[email protected]";
myObj.length; //output: 2

それをfor..inループに表示されないように追加しました:

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

出力:

name:John Doe
email:[email protected]

注意:<IE9ブラウザでは動作しません。


私がこの問題を解決したのは、オブジェクトに格納されているアイテムの数を記録した基本リストの独自の実装を構築することです。 非常にシンプルです。 このようなもの:

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];
   }
}

私はこのようにすべてのオブジェクトに利用可能にしようとします:

Object.defineProperty(Object.prototype, "length", {
get() {
    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;
        };
    }
    return Object.keys(this).length;
},});

console.log({"Name":"Joe","Age":26}.length) //returns 2

私はこれを行う方法は認識していませんが、反復を最小限に抑えるためには、 __count__の存在をチェックしてみてください。それが存在しない場合(つまり、Firefoxでない場合)、オブジェクトを繰り返し処理できます。後で使用するために定義します。例:

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

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

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

いつでもmyobjを参照するこの方法。 __count__関数は__count__ 、再計算されます。





key