JavaScript判断对象是否为空对象的几种方法

简介: JavaScript判断对象是否为空对象的几种方法
var data = {};
var b = $.isEmptyObject(data); //true


判断是否为空对象


1、空对象对应的字符串为 “{}”


var data = {};
var b = JSON.stringify(data) == "{}";
console.log(b); // true


2、for in

var obj = {};
var b = function () {
  for (var key in obj) {
    return false;
  }
  return true;
};
console.log(b()); //true


3、jquery 的 isEmptyObject()方法

这个方法是对第二个方法的封装

var data = {};
var b = $.isEmptyObject(data);
console.log(b); //true


4、Object.getOwnPropertyNames()

Object 对象的 getOwnPropertyNames 方法,获取到对象中的属性名,存到一个数组中,返回数组对象,我们可以通过判断数组的 length 来判断此对象是否为空。

var data = {};
var arr = Object.getOwnPropertyNames(data);
console.log(arr.length == 0); // true


5、ES6 的 Object.keys()

此方法也是返回对象中属性名组成的数组。

var data = {};
var arr = Object.keys(data);
console.log(arr.length == 0); // true


6、JSON.stringify()扩展

JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。

语法:

JSON.stringify(value[, replacer[, space]])


参数说明:

  • value:必需,要转换的 JavaScript 值(通常为对象或数组)。
  • replacer: 可选。用于转换结果的函数或数组。 如果 replacer 为函数,则 JSON.stringify 将调用该函数,并传入每个成员的键和值。使用返回值而不是原始值。 如果此函数返回 undefined,则排除成员。根对象的键是一个空字符串:“”。如果 replacer 是一个数组,则仅转换该数组中具有键值的成员。成员的转换顺序与键在数组中的顺序一样。
  • space:可选,文本添加缩进、空格和换行符,如果 space 是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果 space 大于 10,则文本缩进 10 个空格。space 也可以使用非数字,如:\t。
  • 返回值:返回包含 JSON 文本的字符串。


JSON.stringify()特性具体如下:


(一)

undefined、任意的函数以及 symbol 作为对象属性值时 JSON.stringify() 对跳过(忽略)它们进行序列化。

  • undefined、任意的函数以及 symbol 作为数组元素值时,JSON.stringify() 将会将它们序列化为 null。
  • undefined、任意的函数以及 symbol 被 JSON.stringify() 作为单独的值进行序列化时,都会返回 undefined。


(二)

非数组对象的属性不能保证以特定的顺序出现在序列化后的字符串中。因为 JSON.stringify() 序列化时会忽略一些特殊的值,所以不能保证序列化后的字符串还是以特定的顺序出现(数组除外)。


const data = {
  a: "aaa",
  b: undefined,
  c: Symbol("dd"),
  fn: function () {
    return true;
  },
  d: "ddd",
};
JSON.stringify(data); // 输出:?
// "{"a":"aaa","d":"ddd"}"
JSON.stringify([
  "aaa",
  undefined,
  function aa() {
    return true;
  },
  Symbol("dd"),
  "eee",
]); // 输出:?
// "["aaa",null,null,null,"eee"]"


(三)

JSON.stringify() 将会正常序列化 Date 的值。


JSON.stringify({ now: new Date() });
// "{"now":"2019-12-08T07:42:11.973Z"}"


(四)

转换值如果有 toJSON() 函数,该函数返回什么值,序列化结果就是什么值,并且忽略其他属性的值。

JSON.stringify({
    say: "hello JSON.stringify",
    toJSON: function() {
      return "today i learn";
    }
  })
// "today i learn"


(五)

NaN 和 Infinity 格式的数值及 null 都会被当做 null。

JSON.stringify(NaN)
// "null"
JSON.stringify(null)
// "null"
JSON.stringify(Infinity)
// "null"


(六)

布尔值、数字、字符串的包装对象在序列化过程中会自动转换成对应的原始值。

JSON.stringify([new Number(1), new String("false"), new Boolean(false)]);
// "[1,"false",false]"


(七)

其他类型的对象,包括 Map/Set/WeakMap/WeakSet,仅会序列化可枚举的属性。

// 不可枚举的属性默认会被忽略:
JSON.stringify( 
    Object.create(
        null, 
        { 
            x: { value: 'json', enumerable: false }, 
            y: { value: 'stringify', enumerable: true } 
        }
    )
);
// "{"y":"stringify"}"


(八)

深拷贝最粗暴的方式是JSON.parse(JSON.stringify()),这个方式实现深拷贝会因为序列化的诸多特性从而导致诸多的坑点:比如现在我们要说的循环引用问题。

// 对包含循环引用的对象(对象之间相互引用,形成无限循环)执行此方法,会抛出错误。 
const obj = {
  name: "loopObj"
};
const loopObj = {
  obj
};
// 对象之间形成循环引用,形成闭环
obj.loopObj = loopObj;
// 封装一个深拷贝的函数
function deepClone(obj) {
  return JSON.parse(JSON.stringify(obj));
}
// 执行深拷贝,抛出错误
deepClone(obj)
/**
 VM44:9 Uncaught TypeError: Converting circular structure to JSON
    --> starting at object with constructor 'Object'
    |     property 'loopObj' -> object with constructor 'Object'
    --- property 'obj' closes the circle
    at JSON.stringify (<anonymous>)
    at deepClone (<anonymous>:9:26)
    at <anonymous>:11:13
相关文章
|
1月前
|
JavaScript 前端开发
如何在 JavaScript 中使用 __proto__ 实现对象的继承?
使用`__proto__`实现对象继承时需要注意原型链的完整性和属性方法的正确继承,避免出现意外的行为和错误。同时,在现代JavaScript中,也可以使用`class`和`extends`关键字来实现更简洁和直观的继承语法,但理解基于`__proto__`的继承方式对于深入理解JavaScript的面向对象编程和原型链机制仍然具有重要意义。
|
1月前
|
JavaScript 前端开发 程序员
前端原生Js批量修改页面元素属性的2个方法
原生 Js 的 getElementsByClassName 和 querySelectorAll 都能获取批量的页面元素,但是它们之间有些细微的差别,稍不注意,就很容易弄错!
|
1月前
|
Web App开发 JavaScript 前端开发
如何确保 Math 对象的方法在不同的 JavaScript 环境中具有一致的精度?
【10月更文挑战第29天】通过遵循标准和最佳实践、采用固定精度计算、进行全面的测试与验证、避免隐式类型转换以及持续关注和更新等方法,可以在很大程度上确保Math对象的方法在不同的JavaScript环境中具有一致的精度,从而提高代码的可靠性和可移植性。
|
2月前
|
缓存 监控 前端开发
JavaScript 实现大文件上传的方法
【10月更文挑战第17天】通过以上步骤和方法,我们可以实现较为可靠和高效的大文件上传功能。当然,具体的实现方式还需要根据实际的应用场景和服务器要求进行调整和优化。
|
1月前
|
监控 JavaScript Java
Node.js中内存泄漏的检测方法
检测内存泄漏需要综合运用多种方法,并结合实际的应用场景和代码特点进行分析。及时发现和解决内存泄漏问题,可以提高应用的稳定性和性能,避免潜在的风险和故障。同时,不断学习和掌握内存管理的知识,也是有效预防内存泄漏的重要途径。
130 52
|
1月前
|
JavaScript 前端开发 索引
js中DOM的基础方法
【10月更文挑战第31天】这些DOM基础方法是操作网页文档结构和实现交互效果的重要工具,通过它们可以动态地改变页面的内容、样式和行为,为用户提供丰富的交互体验。
|
1月前
|
缓存 JavaScript UED
js中BOM中的方法
【10月更文挑战第31天】
|
1月前
|
JSON 前端开发 JavaScript
JavaScript中对象的数据拷贝
本文介绍了JavaScript中对象数据拷贝的问题及解决方案。作者首先解释了对象赋值时地址共享导致的值同步变化现象,随后提供了五种解决方法:手动复制、`Object.assign`、扩展运算符、`JSON.stringify`与`JSON.parse`组合以及自定义深拷贝函数。每种方法都有其适用场景和局限性,文章最后鼓励读者关注作者以获取更多前端知识分享。
20 1
JavaScript中对象的数据拷贝
|
1月前
|
缓存 JavaScript 前端开发
JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用
本文深入讲解了 JavaScript 与 DOM 交互的基础及进阶技巧,涵盖 DOM 获取、修改、创建、删除元素的方法,事件处理,性能优化及与其他前端技术的结合,助你构建动态交互的网页应用。
47 5
|
1月前
|
JavaScript 前端开发
js中的bind,call,apply方法的区别以及用法
JavaScript中,`bind`、`call`和`apply`均可改变函数的`this`指向并传递参数。其中,`bind`返回一个新函数,不立即执行;`call`和`apply`则立即执行,且`apply`的参数以数组形式传递。三者在改变`this`指向及传参上功能相似,但在执行时机和参数传递方式上有所区别。
27 1