/**
* 对比两个对象是否一致
* @param {Object} a 对象1
* @param {Object} b 对象2
* @returns {Boolean|undefined} 仅为true时才是一致的
*/
Object.compare = function (a, b) {
// 检查字面量是否一致(适用于所有类型)
if (a + '' !== b + '') return
const ak = Object.keys(a)
// 检查属性量是否一致
if (ak.length !== Object.keys(b).length) return
let i = 0, j = ak.length, k
// 必须使用fo循环遍历属性
for (; i < j; i++) {
k = ak[i]
// 检查是否都存在属性
if (!(k in b)) return
const av = a[k]
const bv = b[k]
// 属性值一致则继续下一项
if (av === bv) continue
const at = this.prototype.toString.call(av)
const bt = this.prototype.toString.call(bv)
// 如果类型不同,或都是对象(此时已排除为null的数据)但递归对比为假,返回假
if (at !== bt || typeof av === 'object' && !compare(av, bv)) return
}
return true
}
/**
* 对数组进行去重:包括复杂数据类型,即不判断引用地址
* 注意:Object.compare()是自定义的方法,作用是对比两个复杂对象除了引用地址外是否一致
*/
Array.prototype.uniqueAndObject: function () {
let obj = {}, t = this.concat(), len = t.length, i, j, k
for (i = 0; i < len; i++) {
k = typeof t[i]
// 是复杂数据则暂时录入到对象中
if (k === 'object' && t[i] || k === 'function') obj[i] = t[i]
// 向后检查简单数据,如果一致则删除索引,直到完全没有
else for (j = t.indexOf(t[i], i + 1); j !== -1; len--) {
t.splice(j, 1)
// 从被删除的位置开始查找,增加效率
j = t.indexOf(t[i], j)
}
}
// 对复杂数据去重
k = Object.keys(obj)
len = k.length
for (i = 0; i < len; i++) {
const v = obj[k[i]]
// 从后向前检查复杂数据,如果一致则删除索引
for (j = len - 1; j > i; j--) if (Object.compare(v, obj[k[j]])) {
t.splice(k[j], 1)
k.splice(j, 1)
len--
}
}
return t
}