题 如何测试空的JavaScript对象?


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

var a = {};

我怎样才能检查是否是这种情况?


1874
2018-03-25 01:39


起源


你使用JSON.js脚本吗?或任何其他JSON库。然后你可以使用JSON.encode()函数将var转换为string然后测试它。 - Thevs


答案:


ECMA 5+

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

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

霍克

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

ExtJS的

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

AngularJS(版本1)

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

Ramda

R.isEmpty({}); // true

3088
2018-03-25 01:49



这是jQuery和下划线之间的性能测试 jsperf.com/isempty-vs-isemptyobject/6 - Mikhail
Object.keys(new Date()).length === 0;所以这个答案可能会产生误导。 - cjbarth
你可以利用这个事实来代替字母串行化: (new Date()).constructor === Date或者相反, ({}).constructor === Object。 - John Nelson
angular.equals({},{}); - Jeremy A. West
Object.keys() 不检查不可枚举的属性或符号。你需要使用 Object.getOwnPropertyNames() 和 Object.getOwnPropertySymbols() 代替。也, Object.getPrototypeOf() 获取对象原型的正确方法。 obj.constructor 可以很容易伪造。例: function Foo() {} Foo.prototype.constructor = Object; (new Foo()).constructor === Object // true。 - Jesse


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

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

747
2018-05-19 14:07



这很好,或者更简单:function isEmpty(object){for(var i in object){return true; } return false; } - Nicholas Kreidberg
在这个功能中,不应该反转真假吗? - namtax
@namtax:不 - 该函数已命名 isEmpty(),所以它应该返回 false 如果它有财产 - Christoph
空对象将扩展默认的Object类,但如果修改了对象原型,则简化的函数将无法考虑:Object.prototype.a ='hi'; var obj = {};警报(obj.a); //输出“hi”isEmpty(obj)//返回false - venimus
您不应该使用第二个示例,因为它是O(n)时间复杂度和O(n)空间复杂度,而第一个是O(1)。 - Brian


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


539
2018-03-22 20:35



嘿!我只花了几个小时调试IE 8问题才发现导致问题的是jQuery.isEmptyObject。如果对象为空,则返回true。 - MFD3000
如果问题根本不是关于jQuery,为什么你发布包括jQuery的答案? - Eru
我知道这是一个旧的评论,但我想知道你的问题@ MFD3000,因为文件说:如果对象为空(如名称所示),则返回true - Александр Фишер
包括jQuery这样的基本任务并不是我所说的正确答案。确实,现在jQuery几乎无处不在,但我们仍然不应该忘记它是围绕一种非常有能力的语言本身构建的。 - Pablo Mescher
这些评论中典型的JS势利。每个人都知道网络上很大一部分JavaScript都是用jQuery编写的,所以如果它已经有了一个用于测试对象的内置方法,那么为jQuery提供一个解决方案是完全可以接受的。成千上万寻求帮助的开发人员可能会发现这个答案很有帮助。没有人说这是唯一的方法。我注意到没有人会对发布解决方案的人使用全部精英 underscore.js... - BadHorsie


您可以使用 Underscore.js

_.isEmpty({}); // true

184
2017-07-12 07:46



或者你可以使用lodash是空的(lodash.com/docs#isEmpty),但与使用jQuery解决方案有什么不同 - 你仍然需要安装一个额外的库。我认为一个vanilla javascript解决方案是意图。 - tfmontague
如果你想在Node.js的后端使用JS,那就不一样了。很少有人会想在后端使用jQuery(一个主要用于DOM操作的前端库)。 - Nahn
@tfmontague下划线在节点应用程序中非常常见,几乎与jQ在客户端一样无处不在。我已经有下划线要求,但没有意识到它有这个功能 - rw-nandemo
Underscore正在被lodash取代。改用它。 - demisx
请注意Date类型,isEmpty总是为Date返回true,请参阅 github.com/jashkenas/underscore/issues/445 - mentat


这是我的首选解决方案:

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

181
2017-11-06 13:48



与IE9 BTW的兼容性问题。 developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... - doublejosh
这个解决方案适用于ie8吗? - Jero Franzani
@Jero Franzani:不,不 - nikoskip
Object.keys({})。长度比(for ... in ...)选项慢10倍 - 我建议避免它作为测试objetc是否为空的方法。 - davidhadas
Object.keys(new Date()).length === 0;所以这个答案可能会产生误导。 - cjbarth


if(Object.getOwnPropertyNames(obj).length === 0){
  //is empty
}

看到 http://bencollier.net/2011/04/javascript-is-an-object-empty/ 


103
2018-01-23 20:07



这在IE8及以下版本中不起作用。 - Stilltorik
这包括不可枚举的属性,以备您关注。
Object.getOwnPropertyNames({})。长度比(for ... in ...)选项慢10倍 - 我建议避免它作为测试objetc是否为空的方法。 - davidhadas
Object.getOwnPropertyNames(new Date()).length === 0;所以这个答案可能会产生误导。 - cjbarth


如何使用JSON.stringify?它几乎适用于所有现代浏览器。

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

62
2018-01-31 10:55



return(JSON.stringify(obj)=='{}') - Vic
这很慢,速度对这种效用很重要。快速性能测试: jsperf.com/empty-object-test - rur
这是一个非常慢的选项 - 我建议使用(for ... in)选项 - davidhadas
它不适用于包含函数的对象。 - Felix Kling


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

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

51
2017-09-22 05:38



这仅在某些其他进程未向您的基础对象添加原型时才有用。为了使其真正可行,您需要测试obj.hasOwnProperty(名称) - mpemburn