We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
var eq, deepEq eq = function (a, b, aStack, bStack) { // 因为 0=== -0 // 所以,先判断 a !== 0 保证了,a和b 是不为0 的, // 其次,判断,a 和b 与 0 和 -0 的关系 // 1/0 == Infinite // 1/-0 == -Infinite if (a === b) return a !== 0 || 1 / a === 1 / b // a和b 中只要有一个是 undefined 或者 null ,就判为 false ,严格模式下 if (a == null || b == null) return false; // NaN 情况 // 如果 a 是NaN ,则判断 b 是不是 NaN if (a !== a) return b !== b var type = typeof a // 经过上面的if 语句,如果是基本类型,如果相等,那么前面就已经有了结论,不会跳到这里, // 这里是排除 基本数据类型的判断,凡是数据基本类型,到了这一步,表明两者并不相等 // 以便下面的对象的深度比较 if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; // 接下来进行对象的深度比较 return deepEq(a, b, aStack, bStack); } deepEq = function (a, b, aStack, bStack) { // 如果 a,b 是underscore 的子类, // 那么就比较 _wrapped 属性值 // 也就是传进来的 obj if (a instanceof _) a = a._wrapped; if (b instanceof _) b = b._wrapped; var className = toString.call(a) // 先用Object.prototype.toString 方法判断是否属于同一类型 if (className !== toString.call(b)) return false // 下面针对不同的情况进行讨论 switch (className) { case '[object RegExp]': case '[object String]': // new String // 正则和字符串的则转换为字符串来比较 return '' + a === '' + b; case '[object Number]': // 如果+a !== +a 那么a = NaN // 此时判断 b 是否是 NaN if (+a !== +a) return +b !== +b; // 将 a 转换为 基本类型 // 如果 a 为 0,判断 1 / +a === 1 / b // 否则判断 +a === +b return +a === 0 ? 1 / +a === 1 / b : +a === +b; // 直接将 Date 和 Boolean 转化为 数字比较 case '[object Date]': case '[object Boolean]': return +a === +b; /** * var a = Symbol(1) var b = Symbol(1) a === b -> false 所以此时比较 时应该就比较 传入 Symbol 的参数 var a = Symbol(1) var b = Symbol(1) Symbol.prototype.valueOf.call(b) === Symbol.prototype.valueOf.call(a) // false Symbol.prototype.toString.call(b) === Symbol.prototype.toString.call(a) // true // 这里好像判断失误了?????????????????????????????????????? */ case '[object Symbol]': return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); } // 判断是否是数组 var areArrays = className === '[object Array]'; if (!areArrays) { // 如果不是数组 // 此时 typeof a| b 是函数。。这样两个函数不管如何直接 false if (typeof a != 'object' || typeof b != 'object') return false; // Objects with different constructors are not equivalent, but `Object`s or `Array`s // from different frames are. // 如果 a 和 b 有着不同的构造函数不一定是不等,如 Object 和 Array 如果在不同的 iframes 的时候 var aCtor = a.constructor, bCtor = b.constructor; // aCtor !== bCtor 说明 两者的构造函数不同 // _.isFunction(aCtor) 保证 能使用 instanceof 来进行判断 // ('constructor' in a && 'constructor' in b) 是防止如下情况: /* var attrs = Object.create(null); attrs.name = "Bob"; eq(attrs, { name: "Bob" }); // 这两个对象应该是相等的 */ if (aCtor !== bCtor && !(_.isFunction(aCtor) && aCtor instanceof aCtor && _.isFunction(bCtor) && bCtor instanceof bCtor) && ('constructor' in a && 'constructor' in b)) { return false; } } aStack = aStack || []; bStack = bStack || []; var length = aStack.length; while (length--) { // 逐个比较其值 第一次时 length = 0 这里不会执行 if (aStack[length] === a) return bStack[length] === b } aStack.push(a) bStack.push(b) if (areArrays) { // 如果是数组 length = a.length if (length !== b.length) return false // 数组长度不等,自然两者不相等 while (length--) { // 递归比较a和b 的一个个子元素,层层剥茧,只要有一个不同,就是false if (!eq(a[length], b[length], aStack, bStack)) return false } } else { // 是纯对象情况 var keys = _.keys(a), key // 获取a 的所有 键 length = keys.length // 键值长度不等,自然不等 if (_.keys(b).length !== length) return false; while (length--) { // Deep compare each member key = keys[length]; // 先看 b 中是否有这个键,有的话,再将a 和 b 对应这个键的键值进行递归比较 if (!(_.has(b, key) && eq(a[key], b[key], aStack, bStack))) return false; } } aStack.pop(); bStack.pop(); return true; } _.isEqual = function (a, b) { return eq(a, b); };
里面参考了JavaScript 中是如何比较两个元素是否 "相同" 的
不过其中也有些疑问,在上面的参考链接里面提出来了问题,可以移步到上面地址
The text was updated successfully, but these errors were encountered:
No branches or pull requests
里面参考了JavaScript 中是如何比较两个元素是否 "相同" 的
不过其中也有些疑问,在上面的参考链接里面提出来了问题,可以移步到上面地址
The text was updated successfully, but these errors were encountered: