Skip to content

Instantly share code, notes, and snippets.

@smallnewer
Last active August 1, 2018 16:31
Show Gist options
  • Save smallnewer/6535788 to your computer and use it in GitHub Desktop.
Save smallnewer/6535788 to your computer and use it in GitHub Desktop.
判断复杂数据类型是否相等。在JS中判断两个对象、函数、数组等是否完全相等是很不方便的。 本例有自己的两个复杂数据类型判断的规则,不适合所有场景。 数组对比中,没有考虑排序问题,是否考虑,有待思考。 ====== 对象对比性能测试:(很卡很长时间) http://jsperf.com/equalobjecttest1 <br> ### result for-in应该比for性能要差,所以判断对象是否相等时,对象属性越多,越浪费时间。1000个属性的对象,一毫秒只能判断2-3个。100个属性的对象大概速度是6/ms 所以在MVC里面处理大数据还是不太实用的,一般的小场景用用无妨。 ### 结论 。。。
/**
* 判断两个数组是否相等
* 浅度相等:两数组toString一样
* 深度相等的判断规则:
* 1.长度相等
* 2.俩数组的每一项:
* 若为数组:参考本函数规则。
* 若为对象:参考equalObject的规则。
* 其他的数据类型,要求===判断为true
* @param {[type]} arr1
* @param {[type]} arr2
* @param {[type]} deepCheck
* @return {[type]}
*/
function equalArray (arr1, arr2, deepCheck) {
if (arr1 === arr2) {
return true;
};
// 长度不等,不用继续判断
if (arr1.length !== arr2.length) {
return false;
};
// 浅度检查
if (!deepCheck) {
return arr1.toString() === arr2.toString();
};
// 判断每个基本数据类型是否一样
var type1, type2; // 数组每一项的数据类型
for (var i = 0; i < arr1.length; i++) {
type1 = type(arr1[i]);
type2 = type(arr2[i]);
// 数据类型不一样,无需判断
if (type1 !== type2) {
return false;
};
if (type1 === "Array") {
if (!equalArray(arr1[i], arr2[i], true)) {
return false;
};
}else if (type1 === 'Object') {
if (!equalObject(arr1[i], arr2[i], true)) {
return false;
};
}else if (arr1[i] !== arr2[i]) {
return false;
};
};
return true;
}
/**
* 对比两个function是否一样
* 主要对比两者toString是否一样,
* 对比会去掉函数名进行对比,其它哪怕差个回车都会返回false
*
* @param {[type]} fn1
* @param {[type]} fn2
* @return {[type]}
*/
function equalFunction (fn1, fn2) {
var type1 = type(fn1),
type2 = type(fn2);
if (type1 !== type2 || type1 !== 'Function') {
return false;
};
if (fn1 === fn2) {
return true;
};
var reg = /^function[\s]*?([\w]*?)\([^\)]*?\){/;
var str1 = fn1.toString().replace(reg,function ($,$1) {
return $.replace($1,"");
});
var str2 = fn2.toString().replace(reg,function ($,$1) {
return $.replace($1,"");
});
console.log(str1,str2);
if (str1 !== str2) {
return false;
};
return true;
}
/**
* 判断两个对象是否相等
* 浅度判断:
* 1.只判断obj的第一层属性总数是否一样
* 2.值的===判断是否为真
* 深度判断:
* 值为对象,参考本规则
* 值为数组,参考equalArray的深度判断
* 值为其他类型,用===判断
* @param {[type]} obj1
* @param {[type]} obj2
* @param {[type]} deepCheck
* @return {[type]}
*/
function equalObject (obj1, obj2, deepCheck) {
if (obj1 === obj2) {
return true;
};
// 属性总数不等,直接返回false
var size1 = 0;
for (var key in obj1){
size1++;
}
var size2 = 0;
for (var key in obj2){
size2++;
}
if (size1 !== size2) {
return false;
};
if (!deepCheck) { // 浅度判断
for (var key in obj1){
if (obj1[key] !== obj2[key]) {
return false;
};
}
return true;
};
var type1,type2;
for (var key in obj1){
type1 = type(obj1[key]);
type2 = type(obj2[key]);
if (type1 !== type2) {
return false;
};
if (type1 === "Object") {
if (!equalObject(obj1[key], obj2[key], true)) {
return false;
};
}else if (type1 === "Array") {
if (!equalArray(obj1[key], obj2[key],true)) {
return false;
};
}else if (obj1[key] !== obj2[key]) {
return false;
};
}
return true;
}
/**
* 返回指定变量的数据类型
* @param {Any} data
* @return {String}
*/
function type (data) {
return Object.prototype.toString.call(data).slice(8, -1);
}
@mengshixing
Copy link

3q

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment