Open cinyearchan opened 1 year ago
这是我按照作者的实现改良了一下
function type(data) {
return Object.prototype.toString.call(data).slice(8, -1).toLowerCase()
}
function equalArray(value, other, enhancer) {
if (value.length !== other.length) {
return false;
}
for (let i = 0; i < value.length; i++) {
if (!isEqual(value[i], other[i], enhancer)) {
return false;
}
}
return true;
}
function equalObject(value, other, enhancer) {
const vKeys = Object.keys(value);
const oKeys = Object.keys(other);
if (vKeys.length !== oKeys.length) {
return false;
}
for (let i = 0; i < vKeys.length; i++) {
const v = value[vKeys[i]];
const o = other[vKeys[i]];
if (!isEqual(v, o, enhancer)) {
return false;
}
}
return true;
}
function isEqual(value, other, enhancer) {
if (value === other) {
return true;
}
const vType = type(value);
const oType = type(other);
if (vType !== oType) {
return false;
}
if (vType === 'array') {
return equalArray(value, other, enhancer);
} else if (vType === 'object') {
return equalObject(value, other, enhancer);
}
const next = () => {
return value === other;
}
if (type(enhancer) === 'function') {
return enhancer(next)(value, other);
}
return next();
}
function nanMiddleware() {
return (next) => (value, other) => {
if (Number.isNaN(value) && Number.isNaN(other)) {
return true;
}
return next(value, other);
}
}
function functionMiddleware() {
return (next) => (value, other) => {
if (type(value) === 'function' && type(other) === 'function') {
return value.toString() === other.toString();
}
return next(value, other);
}
}
function compose(...fns) {
return fns.reduce((a, b) => (...args) => a(b(...args)));
}
const test3 = () => {
}
const test4 = () => {
}
const a1 = {a: NaN, b: test3};
const a2 = {a: NaN, b: test4};
console.log(isEqual(1, NaN, nanMiddleware()));
console.log(isEqual(a1, a2, compose(functionMiddleware(), nanMiddleware())));
console.log(isEqual(a1, a2, compose(nanMiddleware(), functionMiddleware())));
console.log(isEqual(a1, a2, (next) => functionMiddleware(nanMiddleware(next))));
console.log(isEqual([NaN], [NaN], nanMiddleware()));
感谢反馈
https://github.com/jsmini/isequal 这里有一个实战版的代码,可以看看
主要在于非 compose 写法里面: next
应该作为「 nanMiddleware()
返回值」的参数吧。
// 感觉这个 next 也放错地方了
console.log(isEqual(a1, a2, (next) => functionMiddleware(nanMiddleware(next)))); // true
// 我感觉应该是这样的,从上面 compose 的角度来说:
console.log( isEqual(a1, a2, (next) => functionMiddleware(nanMiddleware()(next))) ); // true
// ^?
// 书中是这样的
console.log( isEqual(a1, a2, (next) => functionMiddleware(nanMiddleware())(next)) ); // false
// ^?
借用2楼的代码 @fengyangfifa ,在线 stackblitz link