객체의 키 / 속성 수를 계산하는 가장 빠른 방법은 무엇입니까? 객체를 반복하지 않고 이것을 할 수 있습니까? 즉,하지 않고
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)