Javascript 对象是空的吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4994201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:07:51  来源:igfitidea点击:

Is object empty?

javascript

提问by clarkk

What is the fastest way to check if an object is empty or not?

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

Is there a faster and better way than this:

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

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

    return i;
}

采纳答案by Sean Vieira

I'm assuming that by emptyyou mean "has no properties of its own".

我假设空的意思是“没有自己的属性”。

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

Examples:

例子:

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

If you only need to handle ECMAScript5 browsers, you can use Object.getOwnPropertyNamesinstead of the hasOwnPropertyloop:

如果你只需要处理ECMAScript5 浏览器,你可以使用Object.getOwnPropertyNames代替hasOwnProperty循环:

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

This will ensure that even if the object only has non-enumerable properties isEmptywill still give you the correct results.

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

回答by Jakob

For ECMAScript5 (not supported in all browsers yet though), you can use:

对于 ECMAScript5(虽然并非所有浏览器都支持),您可以使用:

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

回答by johndodo

EDIT: Note that you should probably use ES5 solutioninstead of this since ES5 support is widespreadthese days. It still works for jQuery though.

编辑:请注意,您可能应该使用ES5 解决方案而不是这个,因为如今 ES5 支持很普遍。不过它仍然适用于 jQuery。



Easy and cross-browser way is by using jQuery.isEmptyObject:

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

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

More: http://api.jquery.com/jQuery.isEmptyObject/

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

You need jquery though.

不过你需要jquery。

回答by Brad Koch

Underscoreand lodasheach have a convenient isEmpty()function, if you don't mind adding an extra library.

下划线lodash各有一个方便的isEmpty()功能,如果你不介意添加额外的库。

_.isEmpty({});

回答by davidhadas

Lets put this baby to bed; tested under Node, Chrome, Firefox and IE 9, it becomes evident that for most use cases:

让这个婴儿上床睡觉吧;在 Node、Chrome、Firefox 和 IE 9 下进行测试,很明显,对于大多数用例:

  • (for...in...) is the fastest option to use!
  • Object.keys(obj).length is 10 times slower for empty objects
  • JSON.stringify(obj).length is always the slowest(not surprising)
  • Object.getOwnPropertyNames(obj).length takes longer than Object.keys(obj).lengthcan be much longer on some systems.
  • (for...in...) 是最快的选项!
  • Object.keys(obj).length 对于空对象慢 10 倍
  • JSON.stringify(obj).length 总是最慢的(不足为奇)
  • Object.getOwnPropertyNames(obj).length 花费的时间比 Object.keys(obj).length在某些系统上可能要长得多。

Bottom line performance wise, use:

底线性能明智,使用:

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

or

或者

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

Results under Node:

节点下的结果:

  • first result: return (Object.keys(obj).length === 0)
  • second result: for (var x in obj) { return false; }...
  • third result: for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...
  • forth result: return ('{}' === JSON.stringify(obj))
  • 第一个结果: return (Object.keys(obj).length === 0)
  • 第二个结果: for (var x in obj) { return false; }...
  • 第三个结果: for (var x in obj) { if (obj.hasOwnProperty(x)) return false; }...
  • 第四个结果: return ('{}' === JSON.stringify(obj))

Testing for Object with 0 keys 0.00018 0.000015 0.000015 0.000324

测试具有 0 个键的对象 0.00018 0.000015 0.000015 0.000324

Testing for Object with 1 keys 0.000346 0.000458 0.000577 0.000657

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

Testing for Object with 2 keys 0.000375 0.00046 0.000565 0.000773

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

Testing for Object with 3 keys 0.000406 0.000476 0.000577 0.000904

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

Testing for Object with 4 keys 0.000435 0.000487 0.000589 0.001031

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

Testing for Object with 5 keys 0.000465 0.000501 0.000604 0.001148

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

Testing for Object with 6 keys 0.000492 0.000511 0.000618 0.001269

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

Testing for Object with 7 keys 0.000528 0.000527 0.000637 0.00138

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

Testing for Object with 8 keys 0.000565 0.000538 0.000647 0.00159

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

Testing for Object with 100 keys 0.003718 0.00243 0.002535 0.01381

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

Testing for Object with 1000 keys 0.0337 0.0193 0.0194 0.1337

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

Note that if your typical use case tests a non empty object with few keys, and rarely do you get to test empty objects or objects with 10 or more keys, consider the Object.keys(obj).length option. - otherwise go with the more generic (for... in...) implementation.

请注意,如果您的典型用例测试具有很少键的非空对象,并且您很少测试空对象或具有 10 个或更多键的对象,请考虑使用 Object.keys(obj).length 选项。- 否则采用更通用的 (for... in...) 实现。

Note that Firefox seem to have a faster support for Object.keys(obj).length and Object.getOwnPropertyNames(obj).length, making it a better choice for any non empty Object, but still when it comes to empty objects, the (for...in...) is simply 10 times faster.

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

My 2 cents is that Object.keys(obj).length is a poor idea since it creates an object of keys just to count how many keys are inside, than destroys it! In order to create that object he needs to loop overt the keys... so why use it and not the (for... in...) option :)

我的 2 美分是 Object.keys(obj).length 是一个糟糕的主意,因为它创建了一个键对象只是为了计算里面有多少键,而不是销毁它!为了创建该对象,他需要循环公开键...那么为什么要使用它而不是 (for... in...) 选项:)

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

回答by Alexey Bushnev

Elegant way - use keys

优雅的方式——使用钥匙

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://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

回答by ?ime Vidas

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

回答by Toolkit

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/

http://jsfiddle.net/j7ona6hz/1/

回答by megapotz

Surprised to see so many weak answers on such a basic JS question... The top answer is no good too for these reasons:

很惊讶在这样一个基本的 JS 问题上看到这么多薄弱的答案......由于以下原因,最佳答案也不好:

  1. it generates a global variable
  2. returns trueon undefined
  3. uses for...inwhich is extremely slow by itself
  4. function inside for...inis useless - return falsewithout hasOwnPropertymagic will work fine
  1. 它生成一个全局变量
  2. 收益trueundefined
  3. 使用for...in本身非常慢
  4. 里面的函数for...in没用 -false没有hasOwnProperty魔法的返回会正常工作

In fact there's a simpler solution:

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

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

回答by Pawe? Rychlik

https://lodash.com/docs#isEmptycomes in pretty handy:

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

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