检查对象是否为空的最快方法是什么?

有没有比这更快更好的方法:

function count_obj(obj){
    var i = 0;
    for(var key in obj){
        ++i;
    }

    return i;
}

function isEmpty( o ) {
    for ( var p in o ) { 
        if ( o.hasOwnProperty( p ) ) { return false; }
    }
    return true;
}

我想你说的空是指“没有自己的属性”。

// 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;
}

例子:

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

如果你只需要处理ECMAScript5浏览器,你可以使用Object。getOwnPropertyNames而不是hasOwnProperty循环:

if (Object.getOwnPropertyNames(obj).length > 0) return false;

这将确保即使对象只有不可枚举的属性,isEmpty仍然会给您正确的结果。


对于ECMAScript5(不是所有浏览器都支持),你可以使用:

Object.keys(obj).length === 0

这可能有点俗气。你可以试试这个。

if (JSON.stringify(data).length === 2) {
   // Do something
}

不确定这种方法是否有任何缺点。


下划线和lodash都有一个方便的isEmpty()函数,如果你不介意添加一个额外的库的话。

_.isEmpty({});

编辑:请注意,您可能应该使用ES5解决方案而不是这个,因为ES5支持现在已经广泛使用。但它仍然适用于jQuery。


简单和跨浏览器的方法是使用jQuery.isEmptyObject:

if ($.isEmptyObject(obj))
{
    // do something
}

更多:http://api.jquery.com/jQuery.isEmptyObject/

但是你需要jquery。


不需要图书馆。

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

if (Object.getOwnPropertyNames(obj1).length > 0)
{
 alert('obj1 is empty!');
}

快速联机'dictionary'-objects:

function isEmptyDict(d){for (var k in d) return false; return true}

你可以写一个回退数组。isArray和Object。getOwnPropertyNames不可用

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

很惊讶在这么一个基本的JS问题上看到这么多弱的答案…上面的答案也不好,原因如下:

它生成一个全局变量 在未定义时返回true 用途……它本身非常慢 函数内部为…在是无用的-返回false没有hasOwnProperty魔法将工作良好

事实上,有一个更简单的解决方案:

function isEmpty(value) {
    return Boolean(value && typeof value === 'object') && !Object.keys(value).length;
}

优雅的方式——使用钥匙

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


https://lodash.com/docs#isEmpty非常方便:

_.isEmpty({})   // true
_.isEmpty()     // true
_.isEmpty(null) // true
_.isEmpty("")   // true

情况有多糟?

function(obj){
    for(var key in obj){
        return false; // not empty
    }

    return true; // empty
}

也许你可以用这个决定:

var isEmpty = function(obj) {
  for (var key in obj)
    if(obj.hasOwnProperty(key))
      return false;
  return true;
}

这是我的解决方案

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));
    }
}

解围球


这里有一个好方法

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

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
}

让我们把这个孩子放在床上;在Node, Chrome, Firefox和ie9下测试,很明显,对于大多数用例:

(for…in…)是最快的选择! 种(obj)。对于空对象,长度要慢10倍 JSON.stringify (obj)。长度总是最慢的(这并不奇怪) Object.getOwnPropertyNames (obj)。length比Object.keys(obj)要长。在某些系统上,长度可能更长。

底线性能方面,使用:

function isEmpty(obj) { 
   for (var x in obj) { return false; }
   return true;
}

function isEmpty(obj) {
   for (var x in obj) { if (obj.hasOwnProperty(x))  return false; }
   return true;
}

Node下的结果:

第一个结果:返回(Object.keys(obj)。长度=== 0) 第二个结果:for (var x in obj){返回false;}…… 第三个结果:for (var x in obj) {if (obj. hasownproperty (x))返回false;}…… return ('{}' === JSON.stringify(obj))

测试0键的对象 0.00018 0.000015 0.000015 0.000324

测试带有1个键的对象 0.000346 0.000458 0.000577 0.000657

测试带有2个键的对象 0.000375 0.00046 0.000565 0.000773

测试带有3个键的对象 0.000406 0.000476 0.000577 0.000904

测试带有4个键的对象 0.000435 0.000487 0.000589 0.001031

测试5个键的对象 0.000465 0.000501 0.000604 0.001148

测试有6个键的对象 0.000492 0.000511 0.000618 0.001269

测试带有7个键的对象 0.000528 0.000527 0.000637 0.00138

测试带有8个键的对象 0.000565 0.000538 0.000647 0.00159

测试带有100个键的对象 0.003718 0.00243 0.002535 0.01381

测试具有1000个键的对象 0.0337 0.0193 0.0194 0.1337

请注意,如果您的典型用例测试一个具有很少键的非空对象,并且很少测试空对象或具有10个或更多键的对象,请考虑object .keys(obj)。长度的选择。-否则就用更通用的(for…)在…)的实现。

注意,Firefox似乎对Object.keys(obj)有更快的支持。length和Object.getOwnPropertyNames(obj)。长度,使它成为任何非空对象的更好选择,但当涉及到空对象时,(for…in…)只是快10倍。

我认为Object.keys(obj)。长度是一个糟糕的想法,因为它创建一个键的对象只是为了计算里面有多少个键,而不是破坏它!为了创建该对象,他需要循环显式键…那么为什么用it而不用the (for…)在…)选项:)

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


我修改了肖恩·维埃拉的代码来满足我的需要。Null和undefined根本不算作对象,数字、布尔值和空字符串返回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;


假设你有以下对象:

var obj1= {};
var obj2= {test: "test"};

不要忘记我们不能使用===符号来测试对象是否相等,因为他们得到继承,所以如果你使用ECMA 5和更高版本的javascript,答案很简单,你可以使用下面的函数:

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");
   }
}

结果如下:

isEmpty(obj1); //this returns true
isEmpty(obj2); //this returns false
isEmpty([]); // log in console: isEmpty function only accept an Object

funtion isEmpty(o,i)
{
    for(i in o)
    {
        return!1
    }
    return!0
}

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/