前言
本来是随便翻翻看的心思,打开了 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 了。
随着工作和学习的深入,越来越觉得自己还有很多东西没学到位,我要塌下心来,努力前进!