如何测试一个空的JavaScript对象?


3104

在AJAX请求之后,有时我的应用程序可能返回一个空对象,例如:

var a = {};

如何检查情况呢?


7
您是否使用JSON.js脚本?或任何其他JSON库。然后,您可以使用JSON.encode()函数将var转换为字符串,然后对其进行测试。
Thevs

if( Object.entries(a).length > 0){ //do }
穆罕默德·沙扎德

Answers:


5412

ECMA 5+

// because Object.keys(new Date()).length === 0;
// we have to do some additional check
Object.keys(obj).length === 0 && obj.constructor === Object

不过请注意,这会创建不必要的数组(的返回值keys)。

ECMA 5之前的版本:

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

  return JSON.stringify(obj) === JSON.stringify({});
}

jQuery的

jQuery.isEmptyObject({}); // true

lodash

_.isEmpty({}); // true

下划线

_.isEmpty({}); // true

ek

Hoek.deepEqual({}, {}); // true

ExtJS

Ext.Object.isEmpty({}); // true

AngularJS(版本1)

angular.equals({}, {}); // true

拉姆达

R.isEmpty({}); // true

22
这是jQuery和下划线之间的性能测试jsperf.com/isempty-vs-isemptyobject/6
Mikhail

20
Object.keys(new Date()).length === 0; 所以这个答案可能会误导。
cjbarth '16

6
除了对事物进行分类,您还可以利用这个事实:(new Date()).constructor === Date或相反({}).constructor === Object
约翰·尼尔森

2
angular.equals({},{});
杰里米·A·西

11
Object.keys()不检查不可枚举的属性或符号。您需要使用Object.getOwnPropertyNames()Object.getOwnPropertySymbols()。同样,这Object.getPrototypeOf()是获取对象原型的正确方法。obj.constructor可以很容易地伪造。范例:function Foo() {} Foo.prototype.constructor = Object; (new Foo()).constructor === Object // true
杰西

862

没有简单的方法可以做到这一点。您必须显式地遍历属性:

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

    return true;
}

如果有ECMAScript 5支持,则可以Object.keys()改用:

function isEmpty(obj) {
    return Object.keys(obj).length === 0;
}

56
这可以正常工作,或更简单地说:function isEmpty(object){for(var i in object){return true; 返回false;}
Nicholas Kreidberg 2010年

36
在此函数中是否应该颠倒对与错?
namtax 2010年

25
@namtax:否-该函数已命名isEmpty(),因此false如果它具有属性,则应返回
Christoph 2010年

6
空对象将扩展默认的Object类,但是如果修改了对象原型,则简化功能将失败,请考虑:Object.prototype.a ='hi'; var obj = {}; alert(obj.a); //输出“ hi” isEmpty(obj)//返回false
venimus 2011年

29
您不应该使用第二个示例,因为它是O(n)时间复杂度和O(n)空间复杂度,而第一个示例是O(1)。
布莱恩

571

对于那些同样的问题但使用jQuery的人,可以使用jQuery.isEmptyObject


43
嘿!我只是花了几个小时调试IE 8问题,才发现导致问题的原因是jQuery.isEmptyObject。如果对象为空,则返回true。
MFD3000

162
如果问题根本不是关于jQuery的,为什么还要发布包含jQuery的答案?
Eru 2012年

47
我知道它的一个古老的评论,但我不知道你的问题@ MFD3000,因为实况说:返回true,如果对象是空的(正如其名字表明它)
АлександрФишер

21
包括jQuery这样的基本任务不是我所称的正确答案。的确,当今的jQuery几乎无处不在,但是我们仍然不应忘记它是基于一种非常强大的语言本身构建的。
Pablo Mescher 2013年

53
这些评论中典型的JS势利小人。每个人都知道网络上有很大一部分JavaScript是用jQuery编写的,因此,如果已经有内置的测试对象方法,则在此处为jQuery提供解决方案是完全可以接受的。成千上万寻求帮助的开发人员会发现此答案很有帮助。没有人说这是唯一的方法。我注意到没有人对发布解决方案的人采取一切精英行动underscore.js……
BadHorsie15年

276

这是我的首选解决方案:

var obj = {};
return Object.keys(obj).length; //returns 0 if empty or an integer > 0 if non-empty


3
@杰罗·弗兰扎尼(Jero Franzani):不,不是
nikoskip 2015年

Object.keys({})。length比(for ... in ...)选项要慢10倍-我建议避免使用它来测试objetc是否为空。
davidhadas

10
Object.keys(new Date()).length === 0; 所以这个答案可能会误导。
cjbarth

new Date()不是对象。nd = new Date(); nd.constructor === Object;结果false
pors

204

您可以使用Underscore.js

_.isEmpty({}); // true

19
或者您可以使用lodash为空(lodash.com/docs#isEmpty),但是与使用jQuery解决方案有什么不同-您仍然需要安装其他库。我认为是一种通用的javascript解决方案。
tfmontague 2014年

10
如果要在Node.js后端上使用JS,则有所不同。很少有人会在后端使用jQuery(主要用于DOM操作的前端库)。
Nahn 2014年

3
@tfmontague下划线在节点应用程序上非常常见,几乎与客户端上的jQ一样普遍。我已经有下划线的要求,但没有意识到它具有此功能
rw-nandemo

5
下划线已被lodash取代。改用它。
demisx 2015年

2
请注意日期类型,isEmpty始终为日期返回true,请参见github.com/jashkenas/underscore/issues/445
mentat


80

如何使用JSON.stringify?它几乎在所有现代浏览器中都可用。

function isEmptyObject(obj){
    return JSON.stringify(obj) === '{}';
}

22
return(JSON.stringify(obj)=='{}')
Vic

26
对于这种实用程序,这很慢,速度也很重要。快速的性能测试在这里:jsperf.com/empty-object-test

1
这是一个非常慢的选项-我建议改用(for ... in)选项
davidhadas

2
它不适用于包含函数的对象。
Felix Kling

1
如果对象中有循环引用,也会引发错误。因此它很慢,不可靠,并且可能引发错误并破坏其他所有内容。没有理由使用它。
Burak

62

我只是遇到了类似情况。我不想使用JQuery,而是想使用纯Javascript做到这一点。

我所做的就是使用以下条件,它对我有用。

var obj = {};
if(JSON.stringify(obj) === '{}') { //This will check if the object is empty
   //Code here..
}

对于不等于,请使用: JSON.stringify(obj) !== '{}'

看看这个JSFiddle


4
具有循环引用的对象将失败,因为JSON.stringify专门为它们引发异常。
Pedro MontotoGarcía2014年

1
@PedroMontotoGarcía好吧,一个空对象将如何具有循环引用?
KthProg

8
如果对象不为空(它也应该为它们工作)。
Pedro MontotoGarcía2015年

@Ateszki似乎已经提到了这一点,这是检查对象是否不为空的最慢的方法之一。
2015年

哦,是的。。我错过了。我遇到了想要实现此javascript的情况,经过一番思考,我发现了这种方式。@Ateszki,即使我也是那样。:-)顺便说一句,对此有很多答案,所以我错过了您的答案。
阿尼斯·奈尔

60

旧的问题,但是有问题。如果您的唯一目的是检查对象是否为空,那么包含JQuery并不是一个好主意。相反,深入JQuery的代码,您将得到答案:

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

5
这仅在某些其他进程未向基础对象添加原型的情况下才有用。为了使其真正可行,您需要测试obj.hasOwnProperty(name)
mpemburn,2014年

1
这不会对Christoph从2009
以来

39

如果您使用的是较新的浏览器,则有一种简单的方法。 Object.keys(obj).length == 0


1
keys财产来自哪里?

2
这是ECMAScript 5.1中的标准方法–
下载

1
上面的评论怎么有4个投票?是的,Object.keys是一种标准方法,但是对象没有keys属性。因此,此代码会将任何对象报告为空,除非它偶然碰巧具有一个key用值命名的属性,而该值又又是一个length不为零的属性。可怕!
scravy

Object.keys(new Date()).length === 0; 所以这个答案可能会误导。
cjbarth '16

11
@scravy Object是类Object。Object有一个名为“ keys”的静态方法,该方法接受一个对象作为参数。此方法返回字符串数组,其中字符串是属性名称。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…–
Sgnl

33

对于空对象,使用Object.keys(obj).length(如上文ECMA 5+所建议)的速度要慢10倍!保持老派的选择。

经过在Node,Chrome,Firefox和IE 9下的测试,很明显对于大多数用例:

  • (for ... in ...)是最快的选择!
  • 空对象的Object.keys(obj).length慢10倍
  • JSON.stringify(obj).length总是最慢的(不令人惊讶
  • 在某些系统上,Object.getOwnPropertyNames(obj).length花费的时间比Object.keys(obj).length可以更长。

底线性能明智,请使用:

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

请参阅“对象为空吗?”中的详细测试结果和测试代码


Object.keys速度很慢,但是代码较少。在一个小的页面上,这可能被称为...可能是10次...考虑到额外代码的额外解析时间,这是否还会变慢?
洋基

33

性能

今天,2020.01.17我针对选定的解决方案在Chrome v79.0,Safari v13.0.4和Firefox v72.0的MacOs HighSierra 10.13.6上执行测试。

结论

  • 基于for-in(A,J,L,M)的解决方案最快
  • 基于JSON.stringify(B,K)的解决方案很慢
  • 令人惊讶的Object是,基于(N)的解决方案也很慢

在此处输入图片说明

细节

下面的代码段中提供了15种解决方案。如果要在计算机上运行性能测试,请单击此处

在此处输入图片说明


很多事情是没有意义的,因为您将一切都建立在错误和/或真实返回上。有时编程需要if语句或三元运算符。只是为了
克里斯蒂安·马修

这是最好的答案,谢谢您,第一个解决方案就像一个魅力
Carlos Jesus Arancibia Taborga


27
  1. 只是一种解决方法。如果没有数据,您的服务器能否生成一些特殊属性?

    例如:

    var a = {empty:true};

    然后,您可以轻松地在AJAX回调代码中对其进行检查。

  2. 另一种检查方法:

    if (a.toSource() === "({})")  // then 'a' is empty

编辑:如果您使用任何JSON库(fe JSON.js),则可以尝试JSON.encode()函数并针对空值字符串测试结果。


6
toSource()是非标准的,并且不能在IE或Opera(以及可能未检查的其他浏览器)中使用
Christoph

4
@Thevs:也许您使用的是当前版本ECMA-262的其他副本,但是我没有toSource在15.2.4节中列出属性;根据MDC的说法,它是在JS1.3(即Netscape Navigator 4.06)中引入的,但不是在ECMA-262第三版中!
Christoph

4
@Thevs:好吧,至少有两个重要的浏览器供应商没有实现它,所以它几乎不是实际标准,并且因为它不在ECMA-262中,所以也不是真正的标准……
Christoph

4
即使它确实起作用,toSource()也是这样做的一种可怕方法(原样JSON.encode())。它需要构建一个代表整个对象的字符串,以检查它是否为空。将事物转换为字符串会产生开销,但是如果您的对象具有一百万个属性,则还需要转换一百万个事物,而实际上仅查看一个对象就会知道它不是空的。
Jasper 2014年

4
@thevs的开销更大,即使它的大小可能相同(我不确定在每种情况下也是如此)。但是,该答案涉及一旦找到不同的属性就立即返回false,这使故事完全不同……
Jasper 2014年

25

我创建了一个完整的函数来确定对象是否为空。

它使用Object.keysECMAScript中5(ES5)功能,如果可能的话,以达到最佳性能(见兼容性表)并回退给老式引擎(浏览器)最兼容的方法。

/**
 * Returns true if specified object has no properties,
 * false otherwise.
 *
 * @param {object} object
 * @returns {boolean}
 */
function isObjectEmpty(object)
{
    if ('object' !== typeof object) {
        throw new Error('Object must be specified.');
    }

    if (null === object) {
        return true;
    }

    if ('undefined' !== Object.keys) {
        // Using ECMAScript 5 feature.
        return (0 === Object.keys(object).length);
    } else {
        // Using legacy compatibility mode.
        for (var key in object) {
            if (object.hasOwnProperty(key)) {
                return false;
            }
        }
        return true;
    }
}

这是此代码的要点

这是带有演示和简单测试的JSFiddle

希望对您有所帮助。干杯!


3
对于null对象,这将失败。

嗨@torazaburo!感谢您的通知!我已使用正确的实施方式更新了所有资源。
Slava Fomin II

1
Object.keys({})。length比(for ... in ...)选项要慢10倍-我建议避免使用它来测试objetc是否为空。
davidhadas

1
Object.keys(new Date()).length === 0; 所以这个答案可能会误导。
cjbarth

19

我正在用这个。

function isObjectEmpty(object) {
  var isEmpty = true;
  for (keys in object) {
     isEmpty = false;
     break; // exiting since we found that the object is not empty
  }
  return isEmpty;
}

例如:

var myObject = {}; // Object is empty
var isEmpty  = isObjectEmpty(myObject); // will return true;

// populating the object
myObject = {"name":"John Smith","Address":"Kochi, Kerala"}; 

// check if the object is empty
isEmpty  = isObjectEmpty(myObject); // will return false;

从这里

更新资料

要么

您可以使用isEmptyObject的jQuery实现

function isEmptyObject(obj) {
  var name;
  for (name in obj) {
    return false;
  }
  return true;
}

你好 当您使用数字或布尔值true或false测试此函数时,返回true,这不是正确的结果。isObjectEmpty(true)。isObjectEmpty(false)。isObjectEmpty(1)
iman 2013年

2
我们正在检查对象是否为空,而不是数据类型是否为对象。在您的情况下,检查它是否是对象,我们需要像if(typeof a ===“ object”){...}
kiranvj 2013年

15

下面的示例演示如何测试JavaScript对象是否为空,如果为空,则意味着我们没有自己的属性。

该脚本可在ES6上运行。

const isEmpty = (obj) => {
    if (obj === null ||
        obj === undefined ||
        Array.isArray(obj) ||
        typeof obj !== 'object'
    ) {
        return true;
    }
    return Object.getOwnPropertyNames(obj).length === 0;
};
console.clear();
console.log('-----');
console.log(isEmpty(''));           // true
console.log(isEmpty(33));           // true
console.log(isEmpty([]));           // true
console.log(isEmpty({}));           // true
console.log(isEmpty({ length: 0, custom_property: [] })); // false
console.log('-----');
console.log(isEmpty('Hello'));      // true
console.log(isEmpty([1, 2, 3]));    // true
console.log(isEmpty({ test: 1 }));  // false
console.log(isEmpty({ length: 3, custom_property: [1, 2, 3] })); // false
console.log('-----');
console.log(isEmpty(new Date()));   // true
console.log(isEmpty(Infinity));     // true
console.log(isEmpty(null));         // true
console.log(isEmpty(undefined));    // true


14

根据Object.entries()上的ES2017规范,使用任何现代浏览器均可轻松进行检查-

Object.entries({}).length === 0

3
使用over Object.keys或this有什么好处Object.values
faintsignal

@faintsignal使用这些都很好。我只是添加了条目,因为在评论中找不到它。
维朗特

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

4
例如,当JavaScript库Object在原型链中扩展了方法时,这也将是正确的,因为这是可枚举的,并且for in语句通过可枚举的属性循环。
viam0Zah


12

我会去检查它是否至少有一把钥匙。这就足以告诉我它不是空的。

typeof obj !== "undefined" && Boolean(Object.keys(obj)[0])

1
如果第一个键返回false值怎么办?结果将false是不正确的。
吉米·奥邦约

我已经对此进行了测试。你能举一个可行的例子吗?
Tudor Morar

1
这简短明了,但是如果对象未定义,则会导致运行时错误
Mrinmoy

11

在幕后,所有库中的所有空检查方法都使用对象键检查逻辑。使它易于理解是一种奇怪的方式,您可以将其放入方法中,在此进行描述。

for(key in obj){
   //your work here.
 break;
}

ES5中得到了发展,现在可以简单地使用Object.Keys将对象作为参数的方法来检查对象的密钥长度:

if(Object.keys(obj).length > 0){
 //do your work here
}

或者,如果您正在使用Lodash(必须),则使用。

 _.isEmpty(obj) //==true or false

虽然正确是做if语句的一种奇怪方法-它可能会使在您之后维护代码的人感到困惑。
索伦2014年

10


您可以使用不使用jQuery或其他库的简单代码

var a=({});

//check is an empty object
if(JSON.stringify(a)=='{}') {
    alert('it is empty');
} else {
    alert('it is not empty');
}

JSON类及其功能(解析字符串化)非常有用,但是IE7存在一些问题,您可以使用此简单代码http://www.json.org/js.html对其进行修复。

其他简单方式(simplest Way):
您可以使用这种方式而无需使用jQueryJSON对象。

var a=({});

function isEmptyObject(obj) {
    if(typeof obj!='object') {
        //it is not object, so is not empty
        return false;
    } else {
        var x,i=0;
        for(x in obj) {
            i++;
        }
        if(i>0) {
            //this object has some properties or methods
            return false;
        } else {
            //this object has not any property or method
            return true;
        }
    }
}

alert(isEmptyObject(a));    //true is alerted

JSON.stringify如果对象包含不可字符串化的属性(例如函数或“未定义”),则解决方案将失败,尽管这被认为是一种极端情况。

10

我发现的最好方法:

function isEmpty(obj)
{
    if (!obj)
    {
        return true;
    }

    if (!(typeof(obj) === 'number') && !Object.keys(obj).length)
    {
        return true;
    }

    return false;
}

效劳于:

    t1: {} -> true
    t2: {0:1} -: false
    t3: [] -> true
    t4: [2] -> false
    t5: null -> true
    t6: undefined -> true
    t7: "" -> true
    t8: "a" -> false
    t9: 0 -> true
    t10: 1 -> false

3
我会说0不是空的,因为它实际上是一个数字。其他一切看起来不错,但修复很容易。在第一个if语句中添加它。if (!obj && obj !== 0)
mjwrazor

9

我的看法:

function isEmpty(obj) {
    return !Object.keys(obj).length > 0;
}

var a = {a:1, b:2}
var b = {}

console.log(isEmpty(a)); // false
console.log(isEmpty(b)); // true

只是,我不认为Object.keys()目前所有的浏览器都可以实现。


2
Object.keys(new Date()).length === 0; 所以这个答案可能会误导。
cjbarth '16

3
取决于您是否认为即使从未公开密钥也总是“满”日期。但是我同意,如果那是您的计划,那么为Date构造函数添加一些补充的instanceof check是一个不错的选择。
NiKo

9

如果jQuery和Web浏览器不可用,则underscore.js中还有一个isEmpty函数。

_.isEmpty({}) // returns true

此外,它不假定输入参数为对象。对于列表或字符串或未定义的列表,它也会提供正确的答案。



7

警告!当心JSON的局限性。

javascript:
  obj={  f:function(){}  };
  alert( "Beware!! obj is NOT empty!\n\nobj = {  f:function(){}  }" + 
               "\n\nJSON.stringify( obj )\n\nreturns\n\n" +
                        JSON.stringify( obj ) );

显示

    谨防!!obj不为空!

    obj = {f:function(){}}

    JSON.stringify(obj)

    退货

    {}

7

正确答案是:

const isEmptyObject = obj =>
  Object.getOwnPropertyNames(obj).length === 0 &&
  Object.getOwnPropertySymbols(obj).length === 0 &&
  Object.getPrototypeOf(obj) === Object.prototype;

这将检查:

  • 该对象没有自己的属性(无论可枚举性如何)。
  • 该对象没有自己的属性符号。
  • 该对象的原型为Object.prototype

换句话说,该对象与用创建的对象是无法区分的{}


6

除了Thevs答案:

var o = {};
alert($.toJSON(o)=='{}'); // true

var o = {a:1};
alert($.toJSON(o)=='{}'); // false

这是jquery + jquery.json


我不喜欢使用JSON,因为它不适用于圆形对象结构。
itdoesntwork

2
如果您的页面加载了jQuery $.isEmptyObject(),请使用,不要浪费时间进行非显而易见的转换。
skierpage 2015年

6

提供了扩展对象。代码简洁明了:

制作一个扩展对象:

a = Object.extended({})

检查它的大小:

a.size()
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.