javascript - Este obiectul gol?
Care este cea mai rapidă metodă de a verifica dacă un obiect este gol sau nu?
Există o cale mai rapidă și mai bună decât aceasta:
function count_obj(obj){
var i = 0;
for(var key in obj){
++i;
}
return i;
}
Răspuns #1
Pentru ECMAScript5 (nu este încă suportat în toate browserele), puteți folosi:
Object.keys(obj).length === 0
Răspunsul #2
Presupun că prin gol vă referiți la „nu are proprietăți proprii”.
// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;
function isEmpty(obj) {
// null and undefined are "empty"
if (obj == null) return true;
// Assume if it has a length property with a non-zero value
// that that property is correct.
if (obj.length > 0) return false;
if (obj.length === 0) return true;
// If it isn't an object at this point
// it is empty, but it can't be anything *but* empty
// Is it empty? Depends on your application.
if (typeof obj !== "object") return true;
// Otherwise, does it have any properties of its own?
// Note that this doesn't handle
// toString and valueOf enumeration bugs in IE < 9
for (var key in obj) {
if (hasOwnProperty.call(obj, key)) return false;
}
return true;
}
Exemple:
isEmpty(""), // true
isEmpty(33), // true (arguably could be a TypeError)
isEmpty([]), // true
isEmpty({}), // true
isEmpty({length: 0, custom_property: []}), // true
isEmpty("Hello"), // false
isEmpty([1,2,3]), // false
isEmpty({test: 1}), // false
isEmpty({length: 3, custom_property: [1,2,3]}) // false
Dacă trebuie să gestionezi doar browserele ECMAScript5, poți folosi Object.getOwnPropertyNames în locul buclei hasOwnProperty:
if (Object.getOwnPropertyNames(obj).length > 0) return false;
Acest lucru va asigura că, chiar dacă obiectul are doar proprietăți neenumerabile, isEmpty îți va oferi în continuare rezultatele corecte.
Răspunsul #3
EDITARE: Rețineți că probabil ar trebui să folosiți soluția ES5 în loc de aceasta deoarece suportul pentru ES5 este răspândit în zilele noastre. Totuși, funcționează în continuare pentru jQuery.
O modalitate simplă și compatibilă cu mai multe browsere este prin utilizarea jQuery.isEmptyObject:
if ($.isEmptyObject(obj))
{
// do something
}
Mai multe: http://api.jquery.com/jQuery.isEmptyObject/
Totuși, ai nevoie de jquery.
Răspunsul #4
Underscore și lodash au fiecare o funcție convenabilă isEmpty(), dacă nu te deranjează să adaugi o bibliotecă suplimentară.
_.isEmpty({});
Răspunsul #5
Să punem acest copil la culcare; testat sub Node, Chrome, Firefox și IE 9, devine evident că pentru majoritatea cazurilor de utilizare:
- (for...in...) este cea mai rapidă opțiune de utilizat!
- Object.keys(obj).length este de 10 ori mai lent pentru obiecte goale
- JSON.stringify(obj).length este întotdeauna cel mai lent (nu e surprinzător)
- Object.getOwnPropertyNames(obj).length durează mai mult decât Object.keys(obj).length, putând fi mult mai lung pe unele sisteme.
În ceea ce privește performanța generală, folosește:
function isEmpty(obj) {
for (var x in obj) { return false; }
return true;
}
sau
function isEmpty(obj) {
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }
return true;
}
Rezultate sub Nod:
- primul rezultat:
return (Object.keys(obj).length === 0) - al doilea rezultat:
for (var x in obj) { return false; }... - al treilea rezultat:
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }... - al patrulea rezultat:
return ('{}' === JSON.stringify(obj))
Testarea pentru obiect cu 0 chei 0.00018 0.000015 0.000015 0.000324
Testarea pentru obiect cu 1 cheie 0.000346 0.000458 0.000577 0.000657
Testarea pentru obiect cu 2 chei 0.000375 0.00046 0.000565 0.000773
Testarea pentru obiect cu 3 chei 0.000406 0.000476 0.000577 0.000904
Testarea pentru obiect cu 4 chei 0.000435 0.000487 0.000589 0.001031
Testarea pentru obiect cu 5 chei 0.000465 0.000501 0.000604 0.001148
Testarea pentru obiect cu 6 chei 0.000492 0.000511 0.000618 0.001269
Testarea pentru obiect cu 7 chei 0.000528 0.000527 0.000637 0.00138
Testarea pentru obiect cu 8 chei 0.000565 0.000538 0.000647 0.00159
Testarea pentru obiect cu 100 de chei 0,003718 0,00243 0,002535 0,01381
Testarea pentru obiect cu 1000 de chei 0.0337 0.0193 0.0194 0.1337
Rețineți că dacă cazul dumneavoastră tipic de utilizare testează un obiect nenul cu câteva chei și rareori testați obiecte goale sau obiecte cu 10 sau mai multe chei, luați în considerare opțiunea Object.keys(obj).length. - altfel, utilizați implementarea mai generică (for... in...).
Rețineți că Firefox pare să aibă un suport mai rapid pentru Object.keys(obj).length și Object.getOwnPropertyNames(obj).length, făcându-l o alegere mai bună pentru orice obiect nenul, dar totuși, când vine vorba de obiecte goale, (for...in...) este pur și simplu de 10 ori mai rapid.
Opinia mea este că Object.keys(obj).length este o idee proastă deoarece creează un obiect cu chei doar pentru a număra câte chei sunt în interior, apoi îl distruge! Pentru a crea acel obiect, trebuie să parcurgă cheile... așa că de ce să-l folosești și nu opțiunea (for... in...) :)
var a = {};
function timeit(func,count) {
if (!count) count = 100000;
var start = Date.now();
for (i=0;i<count;i++) func();
var end = Date.now();
var duration = end - start;
console.log(duration/count)
}
function isEmpty1() {
return (Object.keys(a).length === 0)
}
function isEmpty2() {
for (x in a) { return false; }
return true;
}
function isEmpty3() {
for (x in a) { if (a.hasOwnProperty(x)) return false; }
return true;
}
function isEmpty4() {
return ('{}' === JSON.stringify(a))
}
for (var j=0;j<10;j++) {
a = {}
for (var i=0;i<j;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1);
timeit(isEmpty2);
timeit(isEmpty3);
timeit(isEmpty4);
}
a = {}
for (var i=0;i<100;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1);
timeit(isEmpty2);
timeit(isEmpty3);
timeit(isEmpty4, 10000);
a = {}
for (var i=0;i<1000;i++) a[i] = i;
console.log('Testing for Object with '+Object.keys(a).length+' keys')
timeit(isEmpty1,10000);
timeit(isEmpty2,10000);
timeit(isEmpty3,10000);
timeit(isEmpty4,10000);Răspunsul #6
Mod elegant - folosește tastele
var myEmptyObj = {};
var myFullObj = {"key":"value"};
console.log(Object.keys(myEmptyObj).length); //0
console.log(Object.keys(myFullObj).length); //1
https://developer.mozilla.org/ro/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Răspunsul #7
function isEmpty( o ) {
for ( var p in o ) {
if ( o.hasOwnProperty( p ) ) { return false; }
}
return true;
}
Răspuns #8
var x= {}
var y= {x:'hi'}
console.log(Object.keys(x).length===0)
console.log(Object.keys(y).length===0)
true
false
http://jsfiddle.net/j7ona6hz/1/
Răspunsul #9
Surprins să văd atât de multe răspunsuri slabe la o întrebare JS atât de de bază... Răspunsul de top nu este bun nici el din aceste motive:
- generează o variabilă globală
- returnează
truelaundefined - folosește
for...in, care este extrem de lent în sine - funcția din interiorul
for...ineste inutilă - returnareafalsefără magiahasOwnPropertyva funcționa bine
De fapt, există o soluție mai simplă:
function isEmpty(value) {
return Boolean(value && typeof value === 'object') && !Object.keys(value).length;
}
Răspuns #10
https://lodash.com/docs#isEmpty este destul de util:
_.isEmpty({}) // true
_.isEmpty() // true
_.isEmpty(null) // true
_.isEmpty("") // true
