객체의 키 / 속성 수를 계산하는 가장 빠른 방법은 무엇입니까? 객체를 반복하지 않고 이것을 할 수 있습니까? 즉,하지 않고
var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;
(Firefox는 마법의 __count__
속성을 제공 했지만 버전 4 부근에서 제거되었습니다.)
객체의 키 / 속성 수를 계산하는 가장 빠른 방법은 무엇입니까? 객체를 반복하지 않고 이것을 할 수 있습니까? 즉,하지 않고
var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;
(Firefox는 마법의 __count__
속성을 제공 했지만 버전 4 부근에서 제거되었습니다.)
답변:
Node , Chrome, IE 9+, Firefox 4+ 또는 Safari 5+ 와 같은 ES5 호환 환경 에서이 작업을 수행하려면
Object.keys(obj).length
이 코드를 사용할 수 있습니다 :
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;
(Object.prototype.hasOwnProperty.call(obj, k))
?
hasOwnProperty
이 필요한 이유 입니다. 객체 자체에 설정된 속성 만 반환합니다.
obj.hasOwnProperty(k)
(실제로 원래 게시물 에서이 작업을 수행했지만 나중에 업데이트했습니다). hasOwnProperty
는 Object
프로토 타입의 일부이기 때문에 모든 객체에서 사용할 수 있지만,이 방법이 제거되거나 재정의되는 경우는 드물지만 예기치 않은 결과가 발생할 수 있습니다. 그것을 호출함으로써 Object.prototype
조금 더 강력 해집니다. 사용하는 이유 는 프로토 타입 대신 call
메소드를 호출하기 때문 obj
입니다.
당신이 사용하는 경우 Underscore.js를 당신이 사용할 수있는 _.size (감사 @douwe을) :
_.size(obj)
또는 _.keys 를 사용할 수도 있습니다.
_.keys(obj).length
많은 기본 작업을 수행하기위한 엄격한 라이브러리 인 Underscore를 강력히 권장합니다. 가능할 때마다 ECMA5와 일치하고 기본 구현을 연기합니다.
그렇지 않으면 @Avi의 답변을 지원합니다. ECMA5가 아닌 브라우저에 추가 할 수있는 keys () 메소드를 포함하는 MDC 문서에 대한 링크를 추가하도록 편집했습니다.
_.keys(obj).length
내 반환 객체는 때로는 속성이없는 일반 문자열이기 때문에 나에게 가장 효과적이었습니다. _.size(obj)
날 동안, 문자열의 길이를 다시 부여합니다 _.keys(obj).length
반환 0
Object.keys
내부적으로 사용 됩니다. Underscore는 정의되지 않은 for..in
경우 모든 키를 루프 내의 배열로 복사합니다 Object.keys
.
표준 Object 구현 ( ES5.1 Object Internal Properties and Methods )에는 Object
키 / 속성 수를 추적 할 필요가 없으므로 키 Object
를 명시 적으로 또는 암시 적으로 반복하지 않고 크기를 결정하는 표준 방법이 없어야 합니다.
가장 일반적으로 사용되는 대안은 다음과 같습니다.
Object.keys(obj).length;
의 작품 내부 의 키 반복 임시 배열을 계산하고 그 길이를 반환합니다.
이 주제의 다른 곳에서 많은 라이브러리 기반 예제는 라이브러리와 관련하여 유용한 관용구입니다. 그러나 성능 관점에서 볼 때 모든 라이브러리 메소드는 실제로 for-loop 또는 ES5 Object.keys
(네이티브 또는 shimmed)를 캡슐화하므로 완벽한 라이브러리가없는 코드와 비교할 때 얻을 것이 없습니다 .
이러한 for-loop 의 가장 느린 부분 은 .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;
주어진 환경에서 이것이 더 빠른지 아닌지는 벤치마킹의 문제입니다. 어쨌든 매우 제한된 성능 향상을 기대할 수 있습니다.
var k in myobj
성능 이 향상됩니까? 내가 아는 한 함수 만 JavaScript에서 새로운 범위를 선언합니다. 인 루프가이 규칙의 예외입니까?
for (var k in myobj) hasOwn.call(myobj, k) && ++count;
즉, if 문을 간단한 &&?
Object.getOwnPropertyNames(obj).length
; 훨씬 간단합니다.
실제로 성능 문제가 발생하는 경우 적절한 이름의 (크기?) 속성을 늘리거나 줄이는 함수를 사용하여 객체에 속성을 추가하거나 제거하는 호출을 래핑하는 것이 좋습니다.
초기 속성 수를 한 번만 계산하고 거기서부터 계속 진행하면됩니다. 실제 성능 문제가 없다면 귀찮게하지 마십시오. 함수에 그 코드를 감아 서 getNumberOfProperties(object)
끝내십시오.
Avi Flax https://stackoverflow.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.getOwnPropertyNames
, 당신은 여기에 하나만 ...
나는 이것을 할 수있는 방법을 모른다. 그러나 반복을 최소화하기 위해 존재 여부를 확인하려고 시도하고 존재 __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__
함수가 실행되고 다시 계산됩니다.
Object.prototype.__count__
도마뱀 1.9.3에서 제거되고 : whereswalden.com/2010/04/06/... 카운트 / -property -의 물체 - - - 제거되는
Object.__count__
사라졌고, 좋은 탈퇴도있었습니다.
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);});}} */
이것을 피하는 단계 :
키 수를 세려는 객체에 함수를 넣지 마십시오.
별도의 객체를 사용하거나 함수를 위해 특별히 새로운 객체를 만듭니다 (를 사용하여 파일에있는 함수 수를 계산하려는 경우 Object.keys(obj).length
)
또한 예 내 nodejs에서 _ 또는 밑줄 모듈을 사용했습니다.
문서는 여기에서 찾을 수 있습니다 http://underscorejs.org/ 뿐만 아니라 GitHub의 및 기타 다양한 정보의 소스로
마지막으로 lodash 구현 https://lodash.com/docs#size
_.size(obj)
Array(obj).length
: 작동하지 않습니다. http://jsfiddle.net/Jhy8M/
false
나는 아직 방법에 대한 문서를 찾을 수 없습니다했습니다 불구 var obj = { a: true, b: true }
다를 수 있습니다 var obj = {}; obj.a = true; obj.b = true;
또는 W3의 다른 해석 / 의미가있다 단순히 경우를 Chrome에서 채택했습니다.
다음은 세 가지 방법에 대한 성능 테스트입니다.
https://jsperf.com/get-the-number-of-keys-in-an-object
초당 20,735 회
매우 간단하고 호환됩니다. 실행 빠른 하지만 그것은 그 다음 멀리 던져 도착 키의 새로운 배열을 생성하기 때문에 비싼.
return Object.keys(objectToRead).length;
초당 15,734 회
let size=0;
for(let k in objectToRead) {
size++
}
return size;
약간 느리지 만 메모리 사용에 근접하지 않으므로 모바일 또는 다른 소형 컴퓨터에 최적화하려는 경우 더 좋습니다.
초당 953,839,338 회
return mapToRead.size;
기본적으로 Map은 자체 크기를 추적하므로 숫자 필드 만 반환합니다. 다른 방법보다 훨씬 빠릅니다. 객체를 제어 할 수 있으면 대신지도로 변환하십시오.
보낸 사람 : 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 브라우저에서는 작동하지 않습니다.
이 문제를 해결 한 방법은 객체에 저장된 항목 수를 기록하는 기본 목록을 직접 구현하는 것입니다. 매우 간단합니다. 이 같은:
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];
}
}
var i = basiclist.count
while(i--){...}
add
기존 항목을 대체 하는지 또는 remove
존재하지 않는 색인으로 호출 되는지 확인하는 것과 같습니다. 또한 undefined
유효한 항목 값인 경우 목록에 지정된 색인이 있는지 확인할 수 없습니다 .
다음과 같이 모든 객체에 사용할 수 있도록하려고합니다.
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
Google Closure에는 멋진 기능이 있습니다 ... goog.object.getCount (obj)