浅析 Vue:hasChanged

83 阅读1分钟

前言

本来是随便翻翻看的心思,打开了 Vue 的源码,结果在看到 hasChanged 的时候,我不禁陷入了沉思……

上代码

// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#polyfill
export function hasChanged(x: unknown, y: unknown): boolean {
  if (x === y) {
    return x === 0 && 1 / x !== 1 / (y as number)
  } else {
    return x === x || y === y
  }
}

看完代码,我心里有了大大的疑问:为啥不直接返回 x !== y ???

x === y; return x === 0 && 1 / x !== 1 / (y as number)

这里是判断前后都为 0 时,符号是否改变

如果 x = 0,y = -0,虽然 x 和 y 全等,但是:

const x = 0;
const y = -0;
console.log(x === y); // ture
const x1 = 0 / x; // Infinity
const y1 = 0 / y; // -Infinity
console.log(x1 === y1); // false

0 的符号改变了,相关计算的结果也有可能受到影响,所以 0 的符号改变也会返回 true

x !==y; return x === x || y === y

某些情况下,虽然 x !== y,但是也可以算作没有变化,例如:

const x = NaN;
const y = NaN;
console.log(x === y); // false
console.log(x === x); // false 
console.log(y === y); // false

此时,前后值都为 NaN,可以视作没有变化,返回 false

最后

优秀的开源项目中,有许多我前所未见的代码写法,按一位前辈的说法:有些东西你之前觉得没必要,只能说你写得东西太简单,或者太 low 了。

随着工作和学习的深入,越来越觉得自己还有很多东西没学到位,我要塌下心来,努力前进!