JavaScript에서 객체의 키 / 속성 수를 효율적으로 계산하는 방법은 무엇입니까?


Answers

다음 코드를 사용할 수 있습니다.

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;
Question

객체의 키 / 속성 수를 계산하는 가장 빠른 방법은 무엇입니까? 객체를 반복하지 않고이 작업을 수행 할 수 있습니까? 즉하지 않고

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

(파이어 폭스는 마술 __count__ 속성을 제공했지만이 버전은 버전 4 주변에서 제거되었습니다.)




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 사용하여 파일에있는 함수의 수를 계산하려는 경우)

또한 예 내 예제에서 nodejs의 _ 또는 밑줄 모듈을 사용했습니다.

설명서는 Underscore.js 에서 찾을 수 있으며 github 및 기타 다양한 정보에 대한 출처

마지막으로 lodash 구현 https://lodash.com/docs#size

_.size(obj)




표준 객체 구현 ( ES5.1 객체 내부 속성 및 메서드 )에서는 Object 가 키 / 속성 수를 추적 할 필요가 없으므로 키를 명시 적으로 또는 암시 적으로 반복하지 않고 Object 의 크기를 결정할 표준 방법이 없어야합니다 .

가장 일반적으로 사용되는 대안은 다음과 같습니다.

1. ECMAScript의 Object.keys ()

Object.keys(obj).length; 임시 배열을 계산하기 위해 내부적으로 키를 반복 실행하고 길이를 반환합니다.

  • 장점 - 읽기 쉽고 깨끗한 구문. 네이티브 지원을 사용할 수없는 경우 shim을 제외한 라이브러리 또는 사용자 지정 코드 필요 없음
  • 단점 - 배열 생성으로 인한 메모리 오버 헤드입니다.

2. 라이브러리 기반 솔루션

이 주제의 다른 라이브러리 기반 예제는 해당 라이브러리 컨텍스트에서 유용한 관용구입니다. 그러나 성능 관점에서 완벽한 라이브러리 없음 코드와 비교하면 얻을 수있는 모든 라이브러리 메서드는 for 루프 또는 ES5 Object.keys (네이티브 또는 shimmed)를 실제로 캡슐화하므로 아무 것도 얻을 수 없습니다.

3. for-loop 최적화하기

그러한 for 루프의 가장 느린 부분 은 일반적으로 함수 호출 오버 헤드로 인해 .hasOwnProperty() 호출입니다. 따라서 JSON 객체의 항목 수를 원할 때 Object.prototype 을 확장하거나 확장하지 않는다는 것을 안다면 .hasOwnProperty() 호출을 건너 뜁니다.

그렇지 않으면 k local ( 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;

주어진 환경에서 이것이 더 빠르 든 빠르는지는 벤치마킹의 문제입니다. 어쨌든 매우 제한된 성능 향상을 기대할 수 있습니다.




출처 : 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 = "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

참고 : <IE9 브라우저에서는 작동하지 않습니다.







나는 이것을하는 어떤 방법을 모르고 있지만, 반복을 최소한으로 유지하려면 __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__ 함수가 실행되고 다시 계산됩니다.




프로젝트에 Ext JS 4가있는 사용자는 다음을 할 수 있습니다.

Ext.Object.getSize(myobj);

이것의 장점은 모든 Ext 호환 브라우저 (IE6-IE8 포함)에서 작동한다는 것입니다.하지만 다른 권장 솔루션과 마찬가지로 실행 시간이 O (n)보다 좋을 것으로 생각합니다.




위의 jQuery가 작동하지 않으면 다음을 시도하십시오.

$(Object.Item).length



다음을 사용할 수 있습니다 : Object.keys(objectName).length; & Object.values(objectName).length; Object.keys(objectName).length; & Object.values(objectName).length;




Related