如何测试空的JavaScript对象?

fal*_*lmp 2730 javascript

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

var a = {};
Run Code Online (Sandbox Code Playgroud)

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

Ada*_*ner 4767

ECMA 7+:

// because Object.entries(new Date()).length === 0;
// we have to do some additional check
Object.entries(obj).length === 0 && obj.constructor === Object
Run Code Online (Sandbox Code Playgroud)

ECMA 5+:

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

ECMA 5之前:

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

  return JSON.stringify(obj) === JSON.stringify({});
}
Run Code Online (Sandbox Code Playgroud)

jQuery:

jQuery.isEmptyObject({}); // true
Run Code Online (Sandbox Code Playgroud)

洛达什:

_.isEmpty({}); // true
Run Code Online (Sandbox Code Playgroud)

下划线:

_.isEmpty({}); // true
Run Code Online (Sandbox Code Playgroud)

霍克

Hoek.deepEqual({}, {}); // true
Run Code Online (Sandbox Code Playgroud)

ExtJS的

Ext.Object.isEmpty({}); // true
Run Code Online (Sandbox Code Playgroud)

AngularJS(版本1)

angular.equals({}, {}); // true
Run Code Online (Sandbox Code Playgroud)

Ramda

R.isEmpty({}); // true
Run Code Online (Sandbox Code Playgroud)

  • 这是jQuery和下划线之间的性能测试https://jsperf.com/isempty-vs-isemptyobject/6 (19认同)
  • `Object.keys(new Date()).length === 0`; 所以这个答案可能会产生误导. (14认同)
  • `Object.keys()`不检查不可枚举的属性或符号.你需要使用`Object.getOwnPropertyNames()`和`Object.getOwnPropertySymbols()`.另外,`Object.getPrototypeOf()`是获取对象原型的正确方法.`obj.constructor`可以很容易伪造.示例:`function Foo(){} Foo.prototype.constructor = Object; (new Foo()).constructor === Object // true`. (7认同)
  • 你可以利用这个事实来代替字母串行:`(new Date()).constructor === Date`,或者相反,`({}).constructor === Object`. (6认同)
  • angular.equals({},{}); (2认同)
  • @Wronski 是的,有可能,而且它已经在答案中了。但这不是一个很好的解决方案(速度慢,不可靠,有时甚至更差)。 (2认同)

Chr*_*oph 824

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

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

    return true;
}
Run Code Online (Sandbox Code Playgroud)

如果ECMAScript 5支持可用,您可以使用Object.keys():

function isEmpty(obj) {
    return Object.keys(obj).length === 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 这工作正常,或更简单:function isEmpty(object){for(var i in object){return true; } return false; } (56认同)
  • 在这个功能中,不应该反转真假吗? (36认同)
  • 您不应该使用第二个示例,因为它是O(n)时间复杂度和O(n)空间复杂度,而第一个是O(1). (27认同)
  • @namtax:不 - 函数名为`isEmpty()`,所以如果它有一个属性它应该返回`false` (25认同)
  • 空对象将扩展默认的Object类,但如果修改了对象原型,则简化的函数将无法考虑:Object.prototype.a ='hi'; var obj = {}; 警报(obj.a); //输出"hi"isEmpty(obj)//返回false (6认同)
  • @NicholasKreidberg你的函数应该被称为isNOTEmpty.AngusC我不知道你在说什么.BashirMagomedov你不能省略那个测试,因为venimus正确指出了什么.克里斯托夫说得对. (6认同)
  • 或者:`function isObjectEmpty(obj) { for (const i in obj) return false; 返回真;}` (6认同)
  • @Brian我准备了一个快速的jsperf测试,将Object.keys与for-in方法进行比较.似乎表明for-in更快但仍然大致为O(n).http://jsperf.com/empty-object-test (3认同)
  • `Object.keys(obj).length`对我来说是最好的做法. (2认同)

Eri*_*ärd 558

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

  • 如果问题根本不是关于jQuery,为什么你发布包括jQuery的答案? (157认同)
  • 这些评论中典型的JS势利.每个人都知道网络上的大部分JavaScript都是用jQuery编写的,所以如果它已经有了一个用于测试对象的内置方法,那么为jQuery提供解决方案是完全可以接受的.成千上万寻求帮助的开发人员可能会发现这个答案很有帮助.没有人说这是唯一的方法.我注意到没有人对那个发布使用`underscore.js`的解决方案的人表现出所有的精英主义者...... (48认同)
  • 我知道这是一个旧的评论,但我想知道你的问题@ MFD3000,因为文件说:如果对象为空(如名称所示),则返回true (45认同)
  • 嘿!我只花了几个小时调试IE 8问题才发现导致问题的是jQuery.isEmptyObject.如果对象为空,则返回true. (41认同)
  • 包括jQuery这样的基本任务并不是我所说的正确答案.确实,现在jQuery几乎无处不在,但我们仍然不应该忘记它是围绕一种非常有能力的语言本身构建的. (19认同)
  • @Tristan jQuery几乎不是一些随机库,是吗?它是有史以来最受欢迎的JS库,数百万个站点依赖它.我没有看到发布这两个答案的问题,因此有一个纯JS解决方案和一个jQuery解决方案,所以正在jQuery网站上工作的开发人员知道一个快速的内置函数.显然没有人建议您在您的网站上加载整个jQuery库,其唯一目的是使用一个小实用程序功能......显然,对于已经使用jQuery的人来说,这显然是一个解决方案... (10认同)
  • 如果您(或任何插件)修改了Object.prototype,这将不起作用. (3认同)
  • 请注意,当您向它提供一个空的jQuery对象时,jQuery.isEmptyObject会返回**false**(如[其API页面](http://api.jquery.com/jQuery.isEmptyObject/)中所述).它仅适用于常规JavaScript对象. (3认同)
  • @eru他是通灵者,知道他的答案会获得最多的选票.他怎么那样做的? (2认同)
  • @ MFD3000-大声笑... isEmptyObject如果对象为空,则返回true?那是一个问题,因为....?该方法说它确实做到了 (2认同)

小智 249

这是我的首选解决方案:

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

  • `Object.keys(new Date()).length === 0`; 所以这个答案可能会产生误导. (7认同)
  • @Jero Franzani:不,不 (3认同)

Kam*_*ski 201

表现

今天 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 种解决方案。如果您想在您的机器上运行性能测试,请单击此处。此链接已于 2021.07.08 更新,但在此处进行oryginaly 测试- 上表中的结果来自那里(但现在看起来该服务不再有效)。

var log = (s,f) => console.log(`${s} --> {}:${f({})}  {k:2}:${f({k:2})}`);

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

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

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

function D(obj) {
  return Object.entries(obj).length === 0;
}

function E(obj) {
  return Object.getOwnPropertyNames(obj).length === 0;
}

function F(obj) {
  return Object.keys(obj).length === 0 && obj.constructor === Object;
}

function G(obj) {
  return typeof obj === "undefined" || !Boolean(Object.keys(obj)[0]);
}

function H(obj) {
  return Object.entries(obj).length === 0 && obj.constructor === Object;
}

function I(obj) {
  return Object.values( obj  ).every( val => typeof val === "undefined" );
}

function J(obj) {
  for (const key in obj) {
    if (hasOwnProperty.call(obj, key)) {
      return false
    }
  }
  return true;
}

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

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

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

  return true;
}

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

function N(obj) {
  return Object.getOwnPropertyNames(obj).length === 0 &&
  Object.getOwnPropertySymbols(obj).length === 0 &&
  Object.getPrototypeOf(obj) === Object.prototype; 
}

function O(obj) {
  return !(Object.getOwnPropertyNames != undefined ? Object.getOwnPropertyNames(obj).length != 0 : (function(){for(var key in obj) break; return (key != null) && (key != undefined);})())
}

log('A',A);
log('B',B);
log('C',C);
log('D',D);
log('E',E);
log('F',F);
log('G',G);
log('H',H);
log('I',I);
log('J',J);
log('K',K);
log('L',L);
log('M',M);
log('N',N);
log('O',O);
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

如果我的回答有帮助你可以给我买杯咖啡

  • 为了完整起见,我编辑了你的 jsperf 来测试 `obj = {a:1,b:2,c:3}` 和 `for(var i in obj)` 仍然是最快的 https://jsperf.com/object-空通道/2 (6认同)
  • 我创建了一个测试分支,将初始对象更改为包含 10000 个元素,结果确实不同:https://jsbench.me/hplcsahs9e/1。至少在 Firefox 和 Chromium 中,“Object.values”明显获胜,这证实了我的其他测试结果:https://jsben.ch/a3bT7。不管怎样,谢谢你!我只是相信答案需要编辑。 (2认同)
  • Moronix 有比这更好的基准测试。这些片段中的大多数都不是远程等效的,因此比较它们没有什么意义。(K) 和 (L) 基本上是相同的代码(前者缺少“return true”),但其中一个比另一个慢 25%……这表明无论如何差异都很微小,所以应该不重要,它们将与函数调用的成本相形见绌,因为​​函数调用的成本不可避免地会受到 JIT 和垃圾收集抖动以及其他噪音的影响。 (2认同)

Bag*_*ggz 197

您可以使用Underscore.js.

_.isEmpty({}); // true
Run Code Online (Sandbox Code Playgroud)

  • 或者你可以使用lodash是空的(http://lodash.com/docs#isEmpty),但是与使用jQuery解决方案有什么不同 - 你仍然需要安装一个额外的库.我认为一个vanilla javascript解决方案是意图. (19认同)
  • 如果你想在Node.js的后端使用JS,那就不一样了.很少有人会想在后端使用jQuery(一个主要用于DOM操作的前端库). (8认同)
  • 如果添加整个依赖项会让您的超性能依赖应用程序感到沮丧,您可以只安装`_.isEmpty`:`npm i lodash.isempty` (6认同)
  • Underscore正在被lodash取代.改用它. (4认同)
  • @tfmontague下划线在节点应用程序中非常常见,几乎与jQ在客户端无处不在.我已经有下划线要求,但没有意识到它有这个功能 (2认同)
  • 请注意Date类型,isEmpty总是为Date返回true,请参阅https://github.com/jashkenas/underscore/issues/445 (2认同)

es *_*gne 112

if(Object.getOwnPropertyNames(obj).length === 0){
  //is empty
}
Run Code Online (Sandbox Code Playgroud)

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

  • 这在IE8及以下版本中不起作用. (5认同)
  • 这包括不可枚举的属性,以备您关注. (5认同)
  • `Object.getOwnPropertyNames(new Date()).length === 0`; 所以这个答案可能会产生误导. (4认同)

Ate*_*zki 78

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

function isEmptyObject(obj){
    return JSON.stringify(obj) === '{}';
}
Run Code Online (Sandbox Code Playgroud)

  • 这很慢,速度对于这种实用程序很重要.这里的快速性能测试:http://jsperf.com/empty-object-test (25认同)
  • return(JSON.stringify(obj)=='{}') (22认同)
  • 请注意 `JSON.stringify(new Error('gotcha')) === '{}'` 是 `true` (3认同)
  • 这是一个非常慢的选项 - 我建议改用 (for...in) 选项 (2认同)
  • 它不适用于包含函数的对象。 (2认同)
  • 如果对象中有循环引用,它也会抛出错误。所以它很慢,不可靠,可能会抛出错误并破坏其他一切。没有理由使用它。 (2认同)

Jon*_*las 59

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

function isEmptyObject(obj) {
    var name;
    for (name in obj) {
        if (obj.hasOwnProperty(name)) {
            return false;
        }
    }
    return true;
}
Run Code Online (Sandbox Code Playgroud)

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

Ani*_*air 56

我刚遇到类似的情况.我不想使用JQuery,并希望使用纯Javascript来做到这一点.

而我所做的是,使用了以下条件,它对我有用.

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

如果不相等,请使用: JSON.stringify(obj) !== '{}'

看看这个JSFiddle

  • 如果对象不是空的(它也适用于它们). (8认同)
  • 具有循环引用的对象将失败,因为JSON.stringify特别为它们抛出异常. (4认同)
  • @PedroMontotoGarcía 好的,空对象如何具有循环引用? (2认同)
  • @Ateszki 似乎已经提到了这一点,它是检查对象是否不为空的最慢方法之一。 (2认同)

dow*_*oad 35

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

  • @scravy对象是Object类.Object有一个名为'keys'的静态方法,它接受一个对象作为参数.此方法返回字符串数组,其中字符串是属性名称.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys (9认同)
  • 这是ECMAScript 5.1中的[标准方法](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys) (2认同)
  • `Object.keys(new Date()).length === 0`; 所以这个答案可能会产生误导。 (2认同)

小智 29

您可以检查对象键的计数:

if (Object.keys(a).length > 0) {
    // not empty
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么要为已经给出的答案添加评论并给出更糟糕的答案?/sf/answers/2247572911/这是**4月**的第一个答案 (8认同)

dav*_*das 26

使用Object.keys(obj).length(如上面针对ECMA 5+所建议的)对于空对象来说慢10倍!保持旧学校(for ... in)选项.

在Node,Chrom,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;
}
Run Code Online (Sandbox Code Playgroud)

要么

function isEmpty(obj) {
   for (var x in obj) { if (obj.hasOwnProperty(x))  return false; }
   return true;
}
Run Code Online (Sandbox Code Playgroud)

查看Is对象为空的详细测试结果和测试代码


The*_*evs 24

  1. 只是一个解决方法.如果没有数据,您的服务器可以生成一些特殊属性吗?

    例如:

    var a = {empty:true};
    
    Run Code Online (Sandbox Code Playgroud)

    然后,您可以在AJAX回调代码中轻松检查它.

  2. 检查它的另一种方法:

    if (a.toSource() === "({})")  // then 'a' is empty
    
    Run Code Online (Sandbox Code Playgroud)

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

  • `toSource()`是非标准的,不适用于IE或Opera(以及我未检查的其他浏览器) (6认同)
  • @Thevs:也许你有一份ECMA-262当前版本的副本,但我的第15.2.4节没有列出`toSource`属性; 根据MDC,它是在JS1.3(即Netscape Navigator 4.06)中引入的,但它不是在ECMA-262,第3版! (3认同)
  • @Thevs:嗯,至少有两家重要的浏览器供应商没有实现它,所以它几乎不是事实上的标准,因为它不是ECMA-262,它也不是真正的...... (3认同)
  • @Thevs的开销更大,即使它*可能*(我不确定它是在任何情况下)在同一数量级.然而,这个答案涉及一旦找到不同的属性就返回错误,这使得故事全部不同...... (3认同)
  • 即使它确实有效,`toSource()`也是一种可怕的方法(就像`JSON.encode()`).它需要构建一个表示整个对象的字符串,以检查它是否为空.将事物转换为字符串会产生开销,但是如果你的对象拥有一百万个属性,它将需要转换一百万个东西,而实际上只看一个就会让你知道它不是空的. (2认同)

Sla*_* II 23

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

它使用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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是此代码的要点.

这是JSFiddle的演示和简单的测试.

我希望它能帮助别人.干杯!

  • 这对于`null`对象失败了. (3认同)
  • `Object.keys(new Date()).length === 0`; 所以这个答案可能会产生误导。 (2认同)

kir*_*nvj 17

我正在使用这个.

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;
}
Run Code Online (Sandbox Code Playgroud)

例如:

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;
Run Code Online (Sandbox Code Playgroud)

从这里

更新

要么

你可以使用isEmptyObject的jQuery实现

function isEmptyObject ( obj ) {
        var name;
        for ( name in obj ) {
            return false;
        }
        return true;
    }
Run Code Online (Sandbox Code Playgroud)

  • 我们正在检查对象是否为空,而不是数据类型是否为对象。在你的情况下,检查它是否是一个对象,我们需要像 if(typeof a === "object") {...} (2认同)

Gib*_*boK 14

以下示例显示如何测试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
Run Code Online (Sandbox Code Playgroud)


小智 12

function isEmpty(obj) {
  for(var i in obj) { return false; }
  return true;
}
Run Code Online (Sandbox Code Playgroud)

  • 那个报告也是如此,例如,当一个JavaScript库通过原型链扩展`Object`和一个方法时,因为它是可枚举的,并且`for in`语句循环遍历可枚举的属性. (4认同)

Vik*_*ant 12

根据Object.entries()上的ES2017规范,使用任何现代浏览器检查都很简单 -

Object.entries({}).length === 0
Run Code Online (Sandbox Code Playgroud)

  • 使用它比`Object.keys` 或`Object.values` 有什么好处吗? (5认同)

小智 11

jQuery isEmptyObject()对于这种情况有特殊功能:

jQuery.isEmptyObject({}) // true
jQuery.isEmptyObject({ foo: "bar" }) // false
Run Code Online (Sandbox Code Playgroud)

阅读更多信息,请访问http://api.jquery.com/jQuery.isEmptyObject/


ahm*_*och 11

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

for(key in obj){
   //your work here.
 break;
}
Run Code Online (Sandbox Code Playgroud)

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

if(Object.keys(obj).length > 0){
 //do your work here
}
Run Code Online (Sandbox Code Playgroud)

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

 _.isEmpty(obj) //==true or false
Run Code Online (Sandbox Code Playgroud)


Tud*_*rar 11

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

typeof obj !== "undefined" && Boolean(Object.keys(obj)[0])
Run Code Online (Sandbox Code Playgroud)

  • 如果第一个键返回 `false` 值怎么办?结果将是不正确的`false`。 (2认同)

ima*_*man 10


你可以使用这个不使用jQuery或其他库的简单代码

var a=({});

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

JSON类及其函数(parsestringify)非常有用,但是IE7存在一些问题,您可以使用这个简单的代码http://www.json.org/js.html修复它.

其他简单方法(最简单的方法):
您可以使用这种方式而不使用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
Run Code Online (Sandbox Code Playgroud)


小智 10

我找到的最佳方式:

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

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

    return false;
}
Run Code Online (Sandbox Code Playgroud)

效劳于:

    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
Run Code Online (Sandbox Code Playgroud)

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

NiK*_*iKo 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
Run Code Online (Sandbox Code Playgroud)

只是,我不认为所有浏览器Object.keys()目前都在实施.

  • 取决于您是否认为尽管从不公开密钥,但日期总是“已满”。但我同意,如果这是您的计划,那么为 Date 构造函数添加一些补充 instanceof 检查是一个不错的选择。 (3认同)
  • `Object.keys(new Date()).length === 0`; 所以这个答案可能会产生误导。 (2认同)

jic*_*chi 9

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

_.isEmpty({}) // returns true
Run Code Online (Sandbox Code Playgroud)

此外,它不会将输入参数视为对象.对于列表或字符串或未定义,它也将转换正确的答案.


Doh*_*ohd 9

一个更简单的解决方案:var a = {};
案例 a 为空!Object.keys(a).length返回true


Fáb*_*uza 8

2021 - 解决方案

你需要的是Object.entries(obj).length。在原生原型中触摸不好。

您可以创建自己的函数并根据需要使用它。就我而言,我有一个名为的文件夹utils,其中有一个像这样的模块定义:

实用程序/isEmpty.js

export default (obj) => !Object.entries(obj).length
Run Code Online (Sandbox Code Playgroud)

someFileToUse.js

import isEmpty from '~/utils/isEmpty.js'

const obj1 = {};
const obj2 = {somekey: "someValue"};

console.log(isEmpty(obj1)) 
// -> true

console.log(isEmpty(obj2)) 
// -> false
Run Code Online (Sandbox Code Playgroud)


Jes*_*sse 7

正确答案是:

const isEmptyObject = obj =>
  Object.getOwnPropertyNames(obj).length === 0 &&
  Object.getOwnPropertySymbols(obj).length === 0 &&
  Object.getPrototypeOf(obj) === Object.prototype;
Run Code Online (Sandbox Code Playgroud)

这检查:

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

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


Imr*_*mad 7

同时,我们可以有一个函数来检查所有“空”,例如null、undefined、''、' '、{}、[]

var isEmpty = function(data) {
  if (typeof(data) === 'object') {
    if (JSON.stringify(data) === '{}' || JSON.stringify(data) === '[]') {
      return true;
    } else if (!data) {
      return true;
    }
    return false;
  } else if (typeof(data) === 'string') {
    if (!data.trim()) {
      return true;
    }
    return false;
  } else if (typeof(data) === 'undefined') {
    return true;
  } else {
    return false;
  }
}

//Use cases and results.

console.log(isEmpty()); // true
console.log(isEmpty(null)); // true
console.log(isEmpty('')); // true
console.log(isEmpty('  ')); // true
console.log(isEmpty(undefined)); // true
console.log(isEmpty({})); // true
console.log(isEmpty([])); // true
console.log(isEmpty(0)); // false
console.log(isEmpty('Hey')); // false
Run Code Online (Sandbox Code Playgroud)

  • 您不应该在这样的实用程序函数中对数据进行字符串化。想象一下,如果你有一个存储有 1GB 数据的对象,并决定在它上面运行这个函数——你会字符串化整个对象只是为了检查它里面是否有任何东西?只需使用`Object.keys()` (3认同)

Eki*_*kim 6

警告!谨防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 ) );
Run Code Online (Sandbox Code Playgroud)

显示器

    Beware!! obj is NOT empty!

    obj = {  f:function(){}  }

    JSON.stringify( obj )

    returns

    {}


Joã*_*ira 6

纯香草 Javascript,完全向后兼容

function isObjectDefined (Obj) {
  if (Obj === null || typeof Obj !== 'object' ||
    Object.prototype.toString.call(Obj) === '[object Array]') {
    return false
  } else {
    for (var prop in Obj) {
      if (Obj.hasOwnProperty(prop)) {
        return true
      }
    }
    return JSON.stringify(Obj) !== JSON.stringify({})
  }
}

console.log(isObjectDefined()) // false
console.log(isObjectDefined('')) // false
console.log(isObjectDefined(1)) // false
console.log(isObjectDefined('string')) // false
console.log(isObjectDefined(NaN)) // false
console.log(isObjectDefined(null)) // false
console.log(isObjectDefined({})) // false
console.log(isObjectDefined([])) // false
console.log(isObjectDefined({a: ''})) // true
Run Code Online (Sandbox Code Playgroud)


Ant*_*ato 6

要真正接受ONLY {},使用 Lodash 在 Javascript 中做到这一点的最佳方法是:

_.isEmpty(value) && _.isPlainObject(value)
Run Code Online (Sandbox Code Playgroud)


sta*_*ovs 5

除了Thevs答案:

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

var o = {a:1};
alert($.toJSON(o)=='{}'); // false
Run Code Online (Sandbox Code Playgroud)

这是jquery + jquery.json

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

mik*_*ana 5

Sugar.JS为此提供了扩展对象。代码简洁明了:

制作一个扩展对象:

a = Object.extended({})
Run Code Online (Sandbox Code Playgroud)

检查它的大小:

a.size()
Run Code Online (Sandbox Code Playgroud)


cwa*_*ing 5

另一种选择是使用is.js (14kB),而不是jquery (32kB)、lodash (50kB) 或underscore (16.4kB)。is.js 被证明是上述库中最快的库,可用于确定对象是否为空。

http://jsperf.com/check-empty-object-using-libraries

显然,所有这些库并不完全相同,因此如果您需要轻松操作 DOM,那么jquery可能仍然是一个不错的选择,或者如果您需要的不仅仅是类型检查,那么lodashunderscore可能会不错。至于is.js,语法如下:

var a = {};
is.empty(a); // true
is.empty({"hello": "world"}) // false
Run Code Online (Sandbox Code Playgroud)

与 underscore 和 lodash 一样_.isObject(),这不仅适用于 和objects,而且也适用于arraysstrings

在这个库的底层,Object.getOwnPropertyNames它使用的类似于Object.keysObject.getOwnPropertyNames更彻底,因为它将返回可枚举和不可枚举的属性,如此处所述

is.empty = function(value) {
    if(is.object(value)){
        var num = Object.getOwnPropertyNames(value).length;
        if(num === 0 || (num === 1 && is.array(value)) || (num === 2 && is.arguments(value))){
            return true;
        }
        return false;
    } else {
        return value === '';
    }
};
Run Code Online (Sandbox Code Playgroud)

如果您不想引入库(这是可以理解的)并且您知道您只是检查对象(而不是数组或字符串),那么以下函数应该适合您的需求。

function isEmptyObject( obj ) {
    return Object.getOwnPropertyNames(obj).length === 0;
}
Run Code Online (Sandbox Code Playgroud)

这仅比 is.js 快一点,只是因为您没有检查它是否是一个对象。


Dmi*_*iko 5

奇怪的是,我没有遇到一个将对象的与任何条目的存在进行比较的解决方案(也许我在许多给定的解决方案中错过了它)。
我想介绍一下如果对象的所有值都未定义则该对象被视为空的情况:

    const isObjectEmpty = obj => Object.values(obj).every(val => typeof val === "undefined")

    console.log(isObjectEmpty({}))                                 // true
    console.log(isObjectEmpty({ foo: undefined, bar: undefined })) // true
    console.log(isObjectEmpty({ foo: false,     bar: null }))      // false
Run Code Online (Sandbox Code Playgroud)

用法示例

举例来说,假设您有一个函数 ( paintOnCanvas),它会从其参数(xysize)中析构值。如果所有这些都未定义,则它们将被排除在结果选项集中。如果不是,则全部都包括在内。

function paintOnCanvas ({ brush, x, y, size }) {
  const baseOptions = { brush }
  const areaOptions = { x, y, size }
  const options = isObjectEmpty(areaOptions) ? baseOptions : { ...baseOptions, areaOptions }
  // ...
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我能找到的最佳单行解决方案(已更新):

isEmpty = obj => !Object.values(obj).filter(e => typeof e !== 'undefined').length;

console.log(isEmpty({}))                                        // true
console.log(isEmpty({a: undefined, b: undefined}))              // true
console.log(isEmpty({a: undefined, b: void 1024, c: void 0}))   // true

console.log(isEmpty({a: [undefined, undefined]}))               // false
console.log(isEmpty({a: 1}))                                    // false
console.log(isEmpty({a: ''}))                                   // false
console.log(isEmpty({a: null, b: undefined}))                   // false
Run Code Online (Sandbox Code Playgroud)


Blo*_*gic 5

1. 使用 Object.keys

Object.keys 将返回一个数组,其中包含对象的属性名称。如果数组的长度为 0,则我们知道该对象为空。

function isEmpty(obj) {
    return Object.keys(obj).length === 0 && empty.constructor === Object;
}
Run Code Online (Sandbox Code Playgroud)

我们还可以使用 Object.values 和 Object.entries 来检查这一点。这通常是确定对象是否为空的最简单方法。

2. 使用 for...in 循环对象属性

for...in 语句将遍历对象的可枚举属性。

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

    return true;
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我们将循环遍历对象的属性,如果一个对象至少有一个属性,那么它将进入循环并返回 false。如果对象没有任何属性,那么它将返回 true。

#3. 使用 JSON.stringify 如果我们将对象字符串化并且结果只是一个左括号和右括号,我们就知道该对象是空的。

function isEmptyObject(obj){
    return JSON.stringify(obj) === '{}';
}
Run Code Online (Sandbox Code Playgroud)

4. 使用jQuery

jQuery.isEmptyObject(obj); 
Run Code Online (Sandbox Code Playgroud)

5. 使用下划线和 Lodash

_.isEmpty(obj);
Run Code Online (Sandbox Code Playgroud)

资源


Bek*_*caj 5

IsEmpty Object,意外地失去了它的意义,即:它的编程语义,当我们来自雅虎的著名大师将定制的不可枚举对象属性引入 ECMA 并被接受时。

[如果你不喜欢历史 - 请随意跳到工作代码]

我看到了很多很好的答案\这个问题的解决方案\问题。然而,获取 ECMA Script 的最新扩展并不是正确的方法。过去,我们曾经阻止 Web 发展,以保持 Netscape 4.x 以及基于 Netscape 的页面工作和项目的活力,(顺便说一下)这些都是极其原始的落后和特殊的,拒绝使用新的 W3C 标准和主张 [在当时是相当革命性的,并且对编码员友好],而现在却对我们自己的遗产进行了残酷的对待。

杀死 Internet Explorer 11 是完全错误的!是的,一些自“冷战”时代以来一直处于休眠状态的渗透到微软的老战士们同意了这一点——出于各种错误的原因。- 但这并不意味着它就是正确的!

在你的答案中使用新引入的方法\属性并将其作为一个发现(“它一直在那里,但我们没有注意到它”)而不是一个新发明(就其真正含义而言)移交,是有点“绿色”且有害。大约 20 年前,我曾经犯过这样的错误,当时我仍然无法分辨其中已有的内容,并将我能找到参考的所有内容都视为常见的工作解决方案......

向后兼容性很重要!

我们只是还不知道而已。这就是我需要分享我的“数百年历史”通用解决方案的原因,该解决方案仍然向后和向前兼容于不可预见的未来。

对in运算符有很多攻击,但我认为这样做的人终于醒悟了,并真正开始理解和欣赏真正的动态类型语言,例如 JavaScript 及其美丽的本质。

我的方法旨在简单而核心,出于上述原因,我不称其为“空”,因为该词的含义不再准确。Is Enumerable,似乎是具有确切含义的词。

function isEnum( x ) { for( var p in x )return!0; return!1 };
Run Code Online (Sandbox Code Playgroud)

一些用例:

isEnum({1:0})
true

isEnum({})
false

isEnum(null)
false
Run Code Online (Sandbox Code Playgroud)

谢谢阅读!