怎么把两个不同的属性值进行比较_js 深比较和浅比较

1fa2b2a3c92327bb9906991ab89789b0.png

浅比较

概念:浅比较也称引用相等,在js中===是做浅比较,只检查左右两边是否是同一个对象的引用;
{a:1} === {a:1} // false
const m = {a:1};
const n = {a:1};
m === n //false
const m = {a:1};
const n = m;
m === n //true
const m = {a:1};
m === {a:1} //false;
changeValue(params) {
  params.a = 2;
  return params;
}
const m = {a:1};
const n = changeValue(m);
m === n //true
m //{a:2}
n //{a:2}
ps: 这里`changeValue`方法直接修改了传入的参数`params`,这么做造成的后果是把  `m`的值也改变了
(因为javascript中,基本类型是传值调用,引用类型是传引用调用)
所以这种做法在`webstrom`中也会有警告,尽量不要这么做;

如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。

这种引用只局限于对象,如果两个变量指向同一个原始类型的值。那么,变量这时都是值的拷贝。

1 === 1 //true
const m = 1;
const n = 1;
m === n //true
const m = 1;
const n = m;
m === n //true
changeValue(params) {
  params = params + 1;
  return params;
}
const m = 1;
const n = changeValue(m);
m === n //false
m //1
n //2

深比较

深比较也称原值相等,深比较是指检查两个对象的所有属性是否都相等,深比较需要以递归的方式遍历两个对象的所有属性,操作比较耗时,深比较不管这两个对象是不是同一对象的引用。
javascript没有提供深比较的api,需要自己实现,网上有很多,具体查一下吧

实现深比较:首先实现个深拷贝

思路:

1、传递进来的是函数时,不需要操作,直接返回即可
因外执行环境栈中一个名字的函数只能有一个,如果我们自己在克隆一个会把原来的替换掉,这样做没有任何意思;
2,传递的参数是基本的数据类型,不操作直接返回;
3,传递的是对象类型时
(1).正则对象:创建一个新实列存储当前正则返回即可(因为我们的目的是让当前的地址不一样即可)
(2).日期对象创建一个日期实列存储当前日期,
(3)普通对象,创建一个新的实列,循环存储当前的信息;
function _cloneDeep(obj) {
	// 传递进来的如果不是对象,则无需处理,直接返回原始的值即可(一般Symbol和Function也不会进行处理的)
	if (obj === null) return null;
	if (typeof obj !== "object") return obj;

	// 过滤掉特殊的对象(正则对象或者日期对象):直接使用原始值创建当前类的一个新的实例即可,这样克隆后的是新的实例,但是值和之前一样
	if (obj instanceof RegExp) return new RegExp(obj);
	if (obj instanceof Date) return new Date(obj);

	// 如果传递的是数组或者对象,我们需要创建一个新的数组或者对象,用来存储原始的数据
	// obj.constructor 获取当前值的构造器(Array/Object)
	let cloneObj = new obj.constructor;
	for (let key in obj) {
		// 循环原始数据中的每一项,把每一项赋值给新的对象
		if (!obj.hasOwnProperty(key)) break;
		cloneObj[key] = _cloneDeep(obj[key]);
	}
	return cloneObj;
}

2、深比较实现

语法:let res = _assignDeep(obj1,obj2)

思路:

1.首先克隆一份obj1
2.循环拿obj2中的每一项与克隆的obj1比较
如果当前拿出这一项是对象数据类型 并且 克隆的obj1 中相同属性名对应的也是对象数据类型的值,
再次进行深比较,用递归处理一下即可;
其余情况都直接用obj2的值替换obj1的值即可;
function _assignDeep(obj1, obj2) {
    // 先把OBJ1中的每一项深度克隆一份赋值给新的对象
    let obj = _cloneDeep(obj1);

    // 再拿OBJ2替换OBJ中的每一项
    for (let key in obj2) {
        if (!obj2.hasOwnProperty(key)) break;
        let v2 = obj2[key],
            v1 = obj[key];
        // 如果OBJ2遍历的当前项是个对象,并且对应的OBJ这项也是一个对象,此时不能直接替换,需要把两个对象重新合并一下,合并后的最新结果赋值给新对象中的这一项
        if (typeof v1 === "object" && typeof v2 === "object") {
            obj[key] = _assignDeep(v1, v2);
            continue;
        }
        obj[key] = v2;
    }
    return obj;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值