对 JavaScript Object 的一些思考

对 JavaScript Object 的一些思考作者:淮城一只猫日期:2020.03.13修改:2020.03.17本文首发:https://iiong.com/some-thoughts-on-javascript-object/前言前几天在做项目的时候遇到一个关于数组的问题,今天抽空来看看这个问题,因为之前也遇到,但是不长记性所有有了该笔记。之前在项目给后端提交一条数据,这个数...
摘要由CSDN通过智能技术生成

对 JavaScript Object 的一些思考

作者:淮城一只猫

日期:2020.03.13

修改:2020.03.17

本文首发:https://iiong.com/some-thoughts-on-javascript-object/

前言

前几天在做项目的时候遇到一个关于数组的问题,今天抽空来看看这个问题,因为之前也遇到,但是不长记性所有有了该笔记。之前在项目给后端提交一条数据,这个数据是数组类型,但需要改变数组里面的字段又不能改变原来的数组结构,所有我直接赋值新的变量再 Map 遍历修改的时候发现原来的数组结构已经发生改变了。虽然知道其中的原因,所以决定写下笔记,告诫下次不能再犯了。

思考

先看一段简单的例子:

const arr1 = [1, 2, 3];
const arr2 = arr1;
arr2.push(4);
console.log(arr1); // => [1, 2, 3, 4]
console.log(arr2); // => [1, 2, 3, 4]

如果不仔细思考的话,arr1 的结果令人“惊讶”的,学过后端语言的朋友相信都知道这个答案,很显然在 JavaScript 中,数组它是引用传递,所有的对象(Array 也是 对象)也是引用传递。所以意味着在使用等号赋值的时候,俩者引用内存同一个地址值,无论其中一个怎么操作,另一个反馈是同样的结果。

如果换个方式来理解这个引用传递:

const obj1 = {
   a: 'test'};
const obj2 = {
   a: 'test'};
console.log(obj1 === obj2); // => false

MDN 文档对此解释:

当两个操作数都是对象时,JavaScript会比较其内部引用,当且仅当他们的引用指向内存中的相同对象(区域)时才相等,即他们在栈内存中的引用地址相同。

上述声明的 obj1obj2 在声明初始化的时候,在内存中开辟俩个新的地址值,所以在比较的时候,其实是比较俩个地址值是否相等,所以最终会输出 false 结果:

变量名 地址值 对象
obj1 #001 {a: ‘test’}
obj2 #002 {a: ‘test’}

比较对象

字符串比较

其实这个就是将对象使用 JSON.stringify 转换成静态字符串,然后再比较:

// 使用上例变量
const str1 = JSON.stringify(obj1);
const str2 = JSON.stringify(obj2);
console.log(str1 === str2); // => true

虽然这个是最简单方法,但是使用限制也很大,如果对象里面的键值是乱序的,那么这个对比是没啥意义的,例如:

const obj3 = {
   
    test1: 'test1',
    test2: 'test2'
};
const obj4 = {
   
    test2: 'test2',
    test1: 'test1'
};

console.log(JSON.stringify(obj3) === JSON.stringify(obj4)); // => false

俩个对象是一样的,但返回结果却是 false ,所以这个对比看情况使用,那么需要做个方法,不受到键值顺序影响对比。

使用对象属性遍历对比

把对象的 key 提取组成数组,然后对应对象中的 value 是否相等:

const isObjectEqual = (obj1, obj2) => {
   
    // 获取对象属性名数组
    const getAProperty1 = Object.getOwnPropertyNames(obj1);
    const getAProperty2 = Object.getOwnPropertyNames(obj2);

    // 如果获取的属性名数组长度不一样,这说明俩者对象内容不一样
    if (getAProperty1.length !== getAProperty2.length) {
   
        return false;
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值