javascript - orientado - ¿El objeto está vacío?
recorrer array de objetos javascript (24)
Esta pregunta ya tiene una respuesta aquí:
- ¿Cómo pruebo un objeto JavaScript vacío? 42 respuestas
¿Cuál es la forma más rápida de verificar si un objeto está vacío o no?
¿Hay una manera más rápida y mejor que esta:
function count_obj(obj){
var i = 0;
for(var key in obj){
++i;
}
return i;
}
un objeto es una matriz asociativa, aumentada con un prototipo.
El método Object.is () determina si dos valores son el mismo valor.
comparación de objetos: -
Object.is(''LOL'', ''LOL'');// true
Object.is(console, console);// true
Object.is(null, null);// true
Object.is(''ROFL'', ''LOL'');// false
Object.is([], []);// false
Object.is(0, -0);// false
Object.is(NaN, 0/0);// true
if (!Object.is)
{
// do something
}
¿Qué tan malo es esto?
function(obj){
for(var key in obj){
return false; // not empty
}
return true; // empty
}
Aquí hay una buena manera de hacerlo
function isEmpty(obj) {
if (Array.isArray(obj)) {
return obj.length === 0;
} else if (typeof obj === ''object'') {
for (var i in obj) {
return false;
}
return true;
} else {
return !obj;
}
}
Imagina que tienes los siguientes objetos:
var obj1= {};
var obj2= {test: "test"};
No olvide que NO podemos usar el signo === para probar la igualdad de un objeto, ya que obtienen herencia, por lo que si usa ECMA 5 y la versión superior de javascript, la respuesta es fácil, puede usar la siguiente función:
function isEmpty(obj) {
//check if it''s an Obj first
var isObj = obj !== null
&& typeof obj === ''object''
&& Object.prototype.toString.call(obj) === ''[object Object]'';
if (isObj) {
for (var o in obj) {
if (obj.hasOwnProperty(o)) {
return false;
break;
}
}
return true;
} else {
console.error("isEmpty function only accept an Object");
}
}
así que el resultado de la siguiente manera:
isEmpty(obj1); //this returns true
isEmpty(obj2); //this returns false
isEmpty([]); // log in console: isEmpty function only accept an Object
Manera elegante - utilizar teclas
var myEmptyObj = {};
var myFullObj = {"key":"value"};
console.log(Object.keys(myEmptyObj).length); //0
console.log(Object.keys(myFullObj).length); //1
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
Modifiqué el código de Sean Vieira para adaptarlo a mis necesidades. null y undefined no cuentan como objetos en absoluto, y los números, valores booleanos y cadenas vacías devuelven false.
''use strict'';
// Speed up calls to hasOwnProperty
var hasOwnProperty = Object.prototype.hasOwnProperty;
var isObjectEmpty = function(obj) {
// null and undefined are not empty
if (obj == null) return false;
if(obj === false) return false;
if(obj === true) return false;
if(obj === "") return false;
if(typeof obj === "number") {
return false;
}
// 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;
// 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;
};
exports.isObjectEmpty = isObjectEmpty;
No hay necesidad de una biblioteca.
function(){ //must be within a function
var obj = {}; //the object to test
for(var isNotEmpty in obj) //will loop through once if there is a property of some sort, then
return alert(''not empty'')//what ever you are trying to do once
return alert(''empty''); //nope obj was empty do this instead;
}
Para ECMAScript5 (aunque todavía no es compatible con todos los navegadores), puede usar:
Object.keys(obj).length === 0
Puede escribir un respaldo si Array.isArray y Object.getOwnPropertyNames no están disponibles
XX.isEmpty = function(a){
if(Array.isArray(a)){
return (a.length==0);
}
if(!a){
return true;
}
if(a instanceof Object){
if(a instanceof Date){
return false;
}
if(Object.getOwnPropertyNames(a).length == 0){
return true;
}
}
return false;
}
Puede que sea un poco hacky. Puedes probar esto.
if (JSON.stringify(data).length === 2) {
// Do something
}
No estoy seguro si hay alguna desventaja de este método.
Puede ser que puedas usar esta decisión:
var isEmpty = function(obj) {
for (var key in obj)
if(obj.hasOwnProperty(key))
return false;
return true;
}
Sorprendido de ver tantas respuestas débiles en una pregunta tan básica de JS ... La mejor respuesta tampoco es buena por estas razones:
- genera una variable global
- devuelve
true
enundefined
- Usos
for...in
que es extremadamente lento por sí mismo. - la función interna
for...in
es inútil: devolverfalse
sinhasOwnProperty
magic funcionará bien
De hecho hay una solución más simple:
function isEmpty(value){
return Boolean(value && typeof value == ''object'') && !Object.keys(value).length;
});
Supongo que por vacío quiere decir "no tiene propiedades propias".
// 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;
}
Ejemplos:
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
Si solo necesita manejar los navegadores ECMAScript5 , puede usar Object.getOwnPropertyNames
lugar del bucle hasOwnProperty
:
if (Object.getOwnPropertyNames(obj).length > 0) return false;
Esto asegurará que incluso si el objeto solo tiene propiedades no enumerables, isEmpty
aún le dará los resultados correctos.
Vamos a poner a este bebé a la cama; probado bajo Node, Chrome, Firefox e IE 9, se hace evidente que para la mayoría de los casos de uso:
- (para ... en ...) es la opción más rápida de usar!
- Object.keys (obj) .length es 10 veces más lento para objetos vacíos
- JSON.stringify (obj) .length siempre es el más lento (no es sorprendente)
- Object.getOwnPropertyNames (obj) .length tarda más tiempo que Object.keys (obj) .length puede ser mucho más largo en algunos sistemas.
En cuanto al rendimiento de la línea de fondo, use:
function isEmpty(obj) {
for (var x in obj) { return false; }
return true;
}
o
function isEmpty(obj) {
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }
return true;
}
Resultados bajo Nodo:
- primer resultado:
return (Object.keys(obj).length === 0)
- segundo resultado:
for (var x in obj) { return false; }...
for (var x in obj) { return false; }...
- tercer resultado:
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...
for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...
- cuarto resultado:
return (''{}'' === JSON.stringify(obj))
Prueba de Objeto con 0 teclas 0.00018 0.000015 0.000015 0.000324
Prueba de Objeto con 1 teclas 0.000346 0.000458 0.000577 0.000657
Prueba de Objeto con 2 teclas 0.000375 0.00046 0.000565 0.000773
Prueba de Objeto con 3 teclas 0.000406 0.000476 0.000577 0.000904
Prueba de Objeto con 4 teclas 0.000435 0.000487 0.000589 0.001031
Prueba de Objeto con 5 teclas 0.000465 0.000501 0.000604 0.001148
Prueba de Objeto con 6 teclas 0.000492 0.000511 0.000618 0.001269
Prueba de Objeto con 7 teclas 0.000528 0.000527 0.000637 0.00138
Prueba de objetos con 8 teclas 0.000565 0.000538 0.000647 0.00159
Prueba de objetos con 100 teclas 0.003718 0.00243 0.002535 0.01381
Prueba de Objeto con 1000 teclas 0.0337 0.0193 0.0194 0.1337
Tenga en cuenta que si su caso de uso típico prueba un objeto que no está vacío con pocas teclas, y rara vez puede probar objetos vacíos u objetos con 10 o más teclas, considere la opción Object.keys (obj) .length. - De lo contrario, vaya con la implementación más genérica (para ... en ...).
Tenga en cuenta que Firefox parece tener un soporte más rápido para Object.keys (obj) .length y Object.getOwnPropertyNames (obj) .length, por lo que es una mejor opción para cualquier objeto no vacío, pero aún cuando se trata de objetos vacíos, el ( para ... en ...) es simplemente 10 veces más rápido.
Mis 2 centavos es que Object.keys (obj) .length es una mala idea, ya que crea un objeto de claves solo para contar cuántas claves hay en el interior, ¡lo que lo destruye! Para crear ese objeto, necesita hacer un bucle abierto de las teclas ... así que, ¿por qué usarlo y no la opción (para ... en ...) :)
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);
aqui mi solucion
function isEmpty(value) {
if(Object.prototype.toString.call(value) === ''[object Array]'') {
return value.length == 0;
} else if(value != null && typeof value === ''object'') {
return Object.getOwnPropertyNames(value).length == 0;
} else {
return !(value || (value === 0));
}
}
Chears
onliner rápido para objetos ''diccionario'':
function isEmptyDict(d){for (var k in d) return false; return true}
Underscore lodash y la lodash tienen una función isEmpty()
conveniente, si no le importa agregar una biblioteca adicional.
_.isEmpty({});
lodash es bastante útil:
_.isEmpty({}) // true
_.isEmpty() // true
_.isEmpty(null) // true
_.isEmpty("") // true
EDITAR : Tenga en cuenta que probablemente debería usar la solución ES5 en lugar de esto, ya que la compatibilidad con ES5 está widespread estos días. Aunque todavía funciona para jQuery.
La forma sencilla y cruzada del navegador es mediante el uso de jQuery.isEmptyObject
:
if ($.isEmptyObject(obj))
{
// do something
}
Más: http://api.jquery.com/jQuery.isEmptyObject/
Aunque necesitas jquery.
function isEmpty( o ) {
for ( var p in o ) {
if ( o.hasOwnProperty( p ) ) { return false; }
}
return true;
}
funtion isEmpty(o,i)
{
for(i in o)
{
return!1
}
return!0
}
if (Object.getOwnPropertyNames(obj1).length > 0)
{
alert(''obj1 is empty!'');
}
var hasOwnProperty = Object.prototype.hasOwnProperty;
function isArray(a) {
return Object.prototype.toString.call(a) === ''[object Array]''
}
function isObject(a) {
return Object.prototype.toString.call(a) === ''[object Object]''
}
function isEmpty(a) {
if (null == a || "" == a)return!0;
if ("number" == typeof a || "string" == typeof a)return!1;
var b = !0;
if (isArray(a)) {
if (!a.length)return!0;
for (var c = 0; c < a.length; c++)isEmpty(a[c]) || (b = !1);
return b
}
if (isObject(a)) {
for (var d in a)hasOwnProperty.call(a, d) && (isEmpty(a[d]) || (b = !1));
return b
}
return!0
}
var x= {}
var y= {x:''hi''}
console.log(Object.keys(x).length===0)
console.log(Object.keys(y).length===0)
true
false