js对象Object的深比较方法
栏目: JavaScript · 发布时间: 6年前
内容简介:之前文章有些深拷贝和浅拷贝,这篇文章简单总结常用的深度比较方法,这些方法在react中用的特别多,特别是生命周期里面prop对比。因此,react和immutable天生结合性比较好。假设你项目中没有用immutable这种第三方库,那么实现深度比较的方法,在这里总结一下!react中封装一个class然后通过compare2Objects.equal(a,b)进行比较
前言
之前文章有些深拷贝和浅拷贝,这篇文章简单总结常用的深度比较方法,这些方法在react中用的特别多,特别是生命周期里面prop对比。因此,react和immutable天生结合性比较好。假设你项目中没有用immutable这种第三方库,那么实现深度比较的方法,在这里总结一下!
方法一
react中封装一个class
export class compare2Objects {
static hasOwnProperty (obj1, obj2) {
switch (this.typeOf(obj1)) {
case "object":
return Object.prototype.hasOwnProperty.call(obj1, obj2);
case "array":
return this.typeOf(obj2) === "number" && obj2 >= 0 && obj1.length > obj2 ;
default:
return false;
}
};
static typeOf(value){Object.prototype.toString.call(value).replace(/\[|\]/gi, "").split(" ")[1].toLowerCase();}
static length(object){
switch (this.typeOf(object)) {
case "array":
return object.length;
case "object":
return Object.keys(object).length;
default:
return 0;
}
};
static every(obj, func) {this.typeOf(obj) === "array" ? obj.every(func) : Object.entries(obj).every((key, value) => func(value, key))};
static equal(obj1, obj2){
switch (true) {
case this.typeOf(obj1) === "function" && this.typeOf(obj2) === "function":
return true;
case obj1 === obj2:
return true;
case this.typeOf(obj1) === this.typeOf(obj2) && ["object", "array"].includes(this.typeOf(obj1)) && this.length(obj1) === this.length(obj2):
return this.every(obj1, (value, key) => this.hasOwnProperty(obj2, key) && this.equal(value, obj2[key]));
default:
return false;
}
};
}
然后通过compare2Objects.equal(a,b)进行比较
方法二
function deepCompare(x, y) {
var i, l, leftChain, rightChain;
function compare2Objects(x, y) {
var p;
// remember that NaN === NaN returns false
// and isNaN(undefined) returns true
if (isNaN(x) && isNaN(y) && typeof x === 'number' && typeof y === 'number') {
return true;
}
// Compare primitives and functions.
// Check if both arguments link to the same object.
// Especially useful on the step where we compare prototypes
if (x === y) {
return true;
}
// Works in case when functions are created in constructor.
// Comparing dates is a common scenario. Another built-ins?
// We can even handle functions passed across iframes
if ((typeof x === 'function' && typeof y === 'function') ||
(x instanceof Date && y instanceof Date) ||
(x instanceof RegExp && y instanceof RegExp) ||
(x instanceof String && y instanceof String) ||
(x instanceof Number && y instanceof Number)) {
return x.toString() === y.toString();
}
// At last checking prototypes as good as we can
if (!(x instanceof Object && y instanceof Object)) {
return false;
}
if (x.isPrototypeOf(y) || y.isPrototypeOf(x)) {
return false;
}
if (x.constructor !== y.constructor) {
return false;
}
if (x.prototype !== y.prototype) {
return false;
}
// Check for infinitive linking loops
if (leftChain.indexOf(x) > -1 || rightChain.indexOf(y) > -1) {
return false;
}
// Quick checking of one object being a subset of another.
// todo: cache the structure of arguments[0] for performance
for (p in y) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
} else if (typeof y[p] !== typeof x[p]) {
return false;
}
}
for (p in x) {
if (y.hasOwnProperty(p) !== x.hasOwnProperty(p)) {
return false;
} else if (typeof y[p] !== typeof x[p]) {
return false;
}
switch (typeof(x[p])) {
case 'object':
case 'function':
leftChain.push(x);
rightChain.push(y);
if (!compare2Objects(x[p], y[p])) {
return false;
}
leftChain.pop();
rightChain.pop();
break;
default:
if (x[p] !== y[p]) {
return false;
}
break;
}
}
return true;
}
if (arguments.length < 1) {
return true; //Die silently? Don't know how to handle such case, please help...
// throw "Need two or more arguments to compare";
}
for (i = 1, l = arguments.length; i < l; i++) {
leftChain = []; //Todo: this can be cached
rightChain = [];
if (!compare2Objects(arguments[0], arguments[i])) {
return false;
}
}
return true;
}
这两个方法均在项目中用过,比较好用。
以上所述就是小编给大家介绍的《js对象Object的深比较方法》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。