JS 深比较相等

JS 深比较相等

 

首先来看几个例子:

console.log(0 === 0);	// true
console.log('str' === 'str');	// true
console.log(true === true);	// true
console.log(undefined === undefined);	// true
console.log(null === null);	// true
console.log({} === {});	// false
console.log({val: 1} === {val: 1});	// true
console.log([1,2,3] === [1,2,3]);	// true
console.log([1,2,{a: 1}] === [1,2,{a: 1}]);	// true

 

基本类型使用 === 都可以判断相等,而引用类型由于存放于栈中的仅仅是地址,因此看上去一模一样的对象或者数组却不相等,可以看出,=== 仅仅是浅比较。
 

JS 中几种比较算法可以查阅 ES 标准中的相等比较算法

 

那么如何实现深比较呢,直接上代码:

function deepEquals (val1, val2) {
  // NaN 对比情况判断为相同
  if (Number.isNaN(val1) && Number.isNaN(val2)) return true;

  // 是否为对象
  let valIsObject = function (val) {
    return typeof val === 'object' && val !== null;
  }
  if (!valIsObject(val1) || !valIsObject(val2)) return val1 === val2;

  // 当val1和val2都为对象时,若地址相同则相等
  if (val1 === val2) return true;

  // 到这一步可以判断 val1 和 val2 都是对象,为了区分 {} 和 [],如果没有此判断,会导致 deepEquals({}, []) 返回 true
  let isEmptyObj = (Array.isArray(val1) && !Array.isArray(val2)) || (Array.isArray(val2) && !Array.isArray(val1));
  if (isEmptyObj) return false;
  
// 获取键的长度,长度不等则不同,也是为了下面遍历时以短的为基准
  if (Object.keys(val1).length !== Object.keys(val2).length) return false;
  for (let key in val1) {
    if (val1.hasOwnProperty(key)) {
      const isEqual = deepEquals(val1[key], val2[key])
      if (!isEqual)  return isEqual;
    }
  }
  return true;
}

 

通过剪枝提高了执行效率
 

现在使用该深比较函数 deepEquals 来判断下之前的类型:

console.log(deepEquals(0, 0));	// true
console.log(deepEquals('str', 'str'));	// true
console.log(deepEquals(true, true));	// true
console.log(deepEquals(undefined, undefined));	// true
console.log(deepEquals(null, null));	// true
console.log(deepEquals({}, {}));	// true
console.log(deepEquals({val: 1}, {val: 1}));	// true
console.log(deepEquals([1,2,3], [1,2,3]));	// true
console.log(deepEquals([1,2,{a: 1}], [1,2,{a: 1}]));	// true

 

可以看到,通过自定义 deepEquals 函数实现了引用类型的深比较
 

通过深比较,可以辅助实现数组中引用类型去重,相关内容可查阅 JS 数组去重

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值