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
Is object empty?
提问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.getOwnPropertyNames
instead of the hasOwnProperty
loop:
如果你只需要处理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 isEmpty
will 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
回答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 问题上看到这么多薄弱的答案......由于以下原因,最佳答案也不好:
- it generates a global variable
- returns
true
onundefined
- uses
for...in
which is extremely slow by itself - function inside
for...in
is useless - returnfalse
withouthasOwnProperty
magic will work fine
- 它生成一个全局变量
- 收益
true
上undefined
- 使用
for...in
本身非常慢 - 里面的函数
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