【发布时间】:2010-10-15 08:39:34
【问题描述】:
AJAX 请求后,有时我的应用程序可能会返回一个空对象,例如:
var a = {};
如何检查是否是这种情况?
【问题讨论】:
标签: javascript javascript-objects
AJAX 请求后,有时我的应用程序可能会返回一个空对象,例如:
var a = {};
如何检查是否是这种情况?
【问题讨论】:
标签: javascript javascript-objects
我正在使用这个。
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;
}
【讨论】:
// because Object.keys(new Date()).length === 0;
// we have to do some additional check
obj // ? null and undefined check
&& Object.keys(obj).length === 0
&& Object.getPrototypeOf(obj) === Object.prototype
但请注意,这会创建一个不必要的数组(keys 的返回值)。
Pre-ECMA 5:
function isEmpty(obj) {
for(var prop in obj) {
if(Object.prototype.hasOwnProperty.call(obj, prop)) {
return false;
}
}
return JSON.stringify(obj) === JSON.stringify({});
}
jQuery.isEmptyObject({}); // true
_.isEmpty({}); // true
_.isEmpty({}); // true
Hoek.deepEqual({}, {}); // true
Ext.Object.isEmpty({}); // true
angular.equals({}, {}); // true
R.isEmpty({}); // true
【讨论】:
Object.keys(new Date()).length === 0;所以这个答案可能会产生误导。
ECMA5+代码中检查obj.contructor===Object?我们只能使用这个代码obj // ? null and undefined check && Object.keys(obj).length === 0
今天 2020.01.17,我在 Chrome v79.0、Safari v13.0.4 和 Firefox v72.0 上对 macOS High Sierra 10.13.6 进行了测试;选择的解决方案。
for-in(A、J、L、M)的解决方案最快JSON.stringify (B, K) 的解决方案很慢Object(N)的解决方案也很慢下面的 sn-p 中有 15 种解决方案。 如果您想在您的机器上运行性能测试,请单击HERE。 此链接于 2021.07.08 更新,但最初是在 here 执行测试 - 上表中的结果来自那里(但现在看起来该服务不再有效)。
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);
【讨论】:
obj = {a:1,b:2,c:3} 和 for(var i in obj) 仍然是最快的 jsperf.com/object-empty-ch/2
IsEmpty 对象,当我们著名的雅虎大师向 ECMA 引入自定义的不可枚举对象属性并被接受时,意外失去了它的意义,即:它是编程语义 .
[如果你不喜欢历史 - 可以直接跳到工作代码]
我看到很多很好的答案\这个问题的解决方案\问题。 但是,获取 ECMA 脚本的最新扩展并不是正确的方法。我们过去常常阻止 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 };
一些用例:
isEnum({1:0})
true
isEnum({})
false
isEnum(null)
false
感谢阅读!
【讨论】:
isEmptyObject(value) {
return value && value.constructor === Object && Object.keys(value).length === 0;
}
上面的代码足以检查对象的空性。
一篇很好的文章写在how-to-check-if-object-is-empty
【讨论】:
你可以使用 lodash 库来代替普通的 JS 函数。
_.isEmpty({}) // 是的
这将检查数组和对象是否有值并返回布尔值。
【讨论】:
如果ECMAScript 5 support可用,则可以使用Object.keys():
function isEmpty(obj) {
return Object.keys(obj).length === 0;
}
对于 ES3 和更早版本,没有简单的方法可以做到这一点。您必须明确地遍历属性:
function isEmpty(obj) {
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
return false;
}
return true;
}
【讨论】:
isEmpty(),因此如果它有属性,它应该返回false
function isEmpty(object) { for(var i in object) { return true; } return false; } 必须在 11 年后更正。这是更正:function isEmpty(obj) { return !(() => { for (const i in obj) { return true; } return false; })(); }
function isObjectEmpty(obj) { for (const i in obj) return false; return true; }
我能找到的最佳单线解决方案(更新):
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
【讨论】:
Object.keys().length 已经在 2009 年就这个问题提出了建议。stackoverflow.com/a/679937/2943403 所以这个发布的答案一半有缺陷,另一半是多余的。
奇怪的是,我还没有遇到比较对象的值而不是任何条目的存在的解决方案(也许我在许多给定的解决方案中错过了它)。
如果一个对象的所有值都未定义,我想介绍一个对象被认为是空的情况:
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
假设,举例来说,您有一个函数 (paintOnCanvas) 会破坏其参数(x、y 和 size)中的值。如果 all 都未定义,则它们将被排除在结果选项集之外。如果不是,它们都不是,它们都包括在内。
function paintOnCanvas ({ brush, x, y, size }) {
const baseOptions = { brush }
const areaOptions = { x, y, size }
const options = isObjectEmpty(areaOptions) ? baseOptions : { ...baseOptions, areaOptions }
// ...
}
【讨论】:
同时,我们可以使用一个函数来检查所有“空”,例如 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
【讨论】:
Object.keys()
我的看法:
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()。
【讨论】:
Object.keys(new Date()).length === 0;所以这个答案可能会产生误导。
您最想知道的是,对象在使用之前是否具有属性。因此,不要询问isEmpty,然后总是检查if(!isEmpty(obj)) 之类的否定,您可以只测试对象是否不为空并且具有属性
export function hasProperties(obj): boolean {
return obj && obj.constructor === Object && Object.keys(obj).length >= 1;
}
【讨论】:
我喜欢我想出的这个,这里有一些其他答案的帮助。我想我会分享它。
Object.defineProperty(Object.prototype, 'isEmpty', {
get() {
for(var p in this) {
if (this.hasOwnProperty(p)) {return false}
}
return true;
}
});
let users = {};
let colors = {primary: 'red'};
let sizes = {sm: 100, md: 200, lg: 300};
console.log(
'\nusers =', users,
'\nusers.isEmpty ==> ' + users.isEmpty,
'\n\n-------------\n',
'\ncolors =', colors,
'\ncolors.isEmpty ==> ' + colors.isEmpty,
'\n\n-------------\n',
'\nsizes =', sizes,
'\nsizes.isEmpty ==> ' + sizes.isEmpty,
'\n',
''
);
【讨论】:
我们也可以使用 vanilla js 来处理 null 或 undefined 的检查,如下所示,
function isEmptyObject(obj) {
return !!obj && Object.keys(obj).length === 0 && obj.constructor === Object;
}
//tests
isEmptyObject(new Boolean()); // false
isEmptyObject(new Array()); // false
isEmptyObject(new RegExp()); // false
isEmptyObject(new String()); // false
isEmptyObject(new Number()); // false
isEmptyObject(new Function()); // false
isEmptyObject(new Date()); // false
isEmptyObject(null); // false
isEmptyObject(undefined); // false
isEmptyObject({}); // true
【讨论】:
Object.keys 将返回一个数组,其中包含对象的属性名称。如果数组的长度为0,那么我们就知道这个对象是空的。
function isEmpty(obj) {
return Object.keys(obj).length === 0 && empty.constructor === Object;
}
我们也可以使用 Object.values 和 Object.entries 进行检查。 这通常是确定对象是否为空的最简单方法。
for...in 语句将遍历对象的可枚举属性。
function isEmpty(obj) {
for(var prop in obj) {
if(obj.hasOwnProperty(prop))
return false;
}
return true;
}
在上面的代码中,我们会循环遍历对象的属性,如果一个对象至少有一个属性,那么它将进入循环并返回false。如果对象没有任何属性,那么它将返回 true。
#3。使用 JSON.stringify 如果我们对对象进行字符串化并且结果只是一个左括号和右括号,我们就知道该对象是空的。
function isEmptyObject(obj){
return JSON.stringify(obj) === '{}';
}
jQuery.isEmptyObject(obj);
_.isEmpty(obj);
【讨论】:
遇到同样问题但使用jQuery的朋友,可以使用jQuery.isEmptyObject。
【讨论】:
underscore.js...
检查值的新方法是 if(Object.entries(this.props.myarticle).length===0){ }
这里 myarticles 是对象
【讨论】:
这一行代码也有助于回退到旧版浏览器。
var a = {}; //if empty returns false
(Object.getOwnPropertyNames ? Object.getOwnPropertyNames(a).length !== 0 : (function(){ for(var key in a) break; return !!key })()) //Returns False
var a = {b:2}; //if not empty returns true
(Object.getOwnPropertyNames ? Object.getOwnPropertyNames(a).length !== 0 : (function(){ for(var key in a) break; return !!key })()) //Returns true
Object.getOwnPropertyNames 在 ECMA-5 中实现。上面这行代码适用于具有后备功能的旧版浏览器。
另一个快速的解决方案是检查
length的属性Object.keys、Object.entries或Object.values
知识文章:关注这个SO帖子了解Object.keys Vs Object.getOwnPropertyNames之间的详细区别
【讨论】:
我知道这并不能 100% 回答您的问题,但我之前也遇到过类似的问题,以下是我用来解决这些问题的方法:
我有一个可能返回空对象的 API。因为我知道 API 需要哪些字段,所以我只检查是否存在任何必填字段。
例如:
API 返回{} or {agentID: '1234' (required), address: '1234 lane' (opt),...}。
在我的调用函数中,我只会检查
if(response.data && response.data.agentID) {
do something with my agentID
} else {
is empty response
}
这样我就不需要使用那些昂贵的方法来检查对象是否为空。如果对象没有 agentID 字段,我的调用函数的对象将为空。
【讨论】:
这是一个快速、简单的函数:
function isEmptyFunction () {
for (const i in this) return false
return true
}
作为 getter 实现:
Object.defineProperty(Object.prototype, 'isEmpty', { get: isEmptyFunction })
console.log({}.isEmpty) // true
作为单独的函数实现:
const isEmpty = Function.prototype.call.bind(isEmptyFunction)
console.log(isEmpty({})) // true
【讨论】:
Object.hasOwnProperty,这个函数总是返回true(这个函数叫做isEmpty,但是当它不为空的时候返回true,顺便说一句……)。此外,该函数不会自动调用自身。在obj.isEmpty 之后添加()。
我认为第一个被接受的解决方案在大多数情况下都有效,但不是Failsafe。
将是更好且故障安全的解决方案。
function isEmptyObject() {
return toString.call(obj) === "[object Object]"
&& Object.keys(obj).length === 0;
}
或在 ES6/7 中
const isEmptyObject = () => toString.call(obj) === "[object Object]"
&& Object.keys(obj).length === 0;
使用这种方法,如果 obj 设置为 undefined 或 null,则代码不会中断。 并返回 null。
【讨论】:
let jsObject = JSON.parse(JSON.stringify(obj), (key, value) => {
if (value === null ||
value === '' ||
(value.constructor === Object && Object.entries(value).length === 0) ||
(value.constructor === Array && value.length === 0)) {
return undefined
}
return value
})
这将递归过滤掉所有无效字段。
【讨论】:
对于空对象,使用 Object.keys(obj).length(如上面对 ECMA 5+ 的建议)会慢 10 倍!保留老派(for...in)选项。
在 Node、Chrome、Firefox 和 IE 9 下测试,很明显对于大多数用例:
底线性能明智,使用:
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;
}
在Is object empty?查看详细的测试结果和测试代码
【讨论】:
Object.keys 很慢,但代码更少。在一个小页面上,它被调用...可能 10 次...考虑到额外代码的额外解析时间,这仍然会更慢吗?
isEmpty 表示任何类型的值
/* eslint-disable no-nested-ternary */
const isEmpty = value => {
switch (typeof value) {
case 'undefined':
return true;
case 'object':
return value === null
? true
: Array.isArray(value)
? !value.length
: Object.entries(value).length === 0 && value.constructor === Object;
case 'string':
return !value.length;
default:
return false;
}
};
【讨论】:
这与在 lodash 源中检查对象的方式类似:
const isEmpty = value => {
for (const key in value) {
if (hasOwnProperty.call(value, key)) {
return false
}
}
return true;
}
但是还有很多其他方法可以做到这一点。
【讨论】:
要真正接受 ONLY {},使用 Lodash 在 Javascript 中做到这一点的最佳方法是:
_.isEmpty(value) && _.isPlainObject(value)
【讨论】:
纯原生 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
【讨论】:
export function isObjectEmpty(obj) {
return (
Object.keys(obj).length === 0 &&
Object.getOwnPropertySymbols(obj).length === 0 &&
obj.constructor === Object
);
}
这包括检查包含符号属性的对象。
Object.keys 不检索符号属性。
【讨论】:
这是我想出来的,用来判断对象中是否有任何非空值。
function isEmpty(obj: Object): Boolean {
for (const prop in obj) {
if (obj.hasOwnProperty(prop)) {
if (obj[prop] instanceof Object) {
const rtn = this.isEmpty(obj[prop]);
if (rtn === false) {
return false;
}
} else if (obj[prop] || obj[prop] === false) {
return false;
}
}
}
return true;
}
【讨论】:
下面的例子展示了如何测试一个 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
【讨论】: