我们比较两个对象,比较好的一种办法是直接【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。比较两个对象的hash值,对于相同结构和【未经授权禁止转载】转载请注明出处:www.tangshuang.net内容的对象,hash值应该相等。怎么获取转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】对象的hash值?
【本文首发于唐霜的博客】【版权所有,侵权必究】【本文受版权保护】著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】/**
* 获取一个字符串的hash
* @param {*} str
*/
function getStringHash(str) {
let hash = 5381
let i = str.length
while(i) {
hash = (hash * 33) ^ str.charCodeAt(--i)
}
return hash >>> 0
}
/**
* 格式化对象,类似JSON.stringify,但是支持自引用嵌套
* @param {*} obj
*/
export function stringifyObject(obj) {
const exists = [obj] // 存储已经处理过的,避免死循环
const used = [] // 记录被用到的引用标记
const stringifyObjectByKeys = (obj) => {
if (isArray(obj)) {
let items = obj.map((item) => {
if (item && typeof item === 'object') {
return stringifyObjectByKeys(item)
}
else {
return JSON.stringify(item)
}
})
let str = '[' + items.join(',') + ']'
return str
}
let str = '{'
let keys = Object.keys(obj)
let total = keys.length
keys.sort()
keys.forEach((key, i) => {
let value = obj[key]
str += key + ':'
if (value && typeof value === 'object') {
let index = exists.indexOf(value)
if (index > -1) {
str += '#' + index
used.push(index)
}
else {
exists.push(value)
let num = exists.length - 1
str += '#' + num + stringifyObjectByKeys(value)
}
}
else {
str += JSON.stringify(value)
}
if (i < total - 1) {
str += ','
}
})
str += '}'
return str
}
let str = stringifyObjectByKeys(obj)
exists.forEach((item, i) => {
if (!used.includes(i)) {
str = str.replace(new RegExp(`:#${i}`, 'g'), ':')
}
})
if (used.includes(0)) {
str = '#0' + str
}
return str
}
/**
* 获取一个对象的hash值
* @param {*} obj
*/
export function getObjectHash(obj) {
if (typeof obj !== 'object') {
return
}
let str = stringifyObject(obj)
let hash = getStringHash(str)
return hash
}
这里面考虑到了一个非常严重的问题,就是当未经授权,禁止复制转载。【未经授权禁止转载】一个对象如果存在自引用的情况,普通的遍历【转载请注明来源】本文作者:唐霜,转载请注明出处。会引起死循环而导致程序挂掉,但这个函数不【原创内容,转载请注明出处】【原创不易,请尊重版权】会,它会用一个临时变量去记录已经处理过的原创内容,盗版必究。【本文受版权保护】对象,如果在下一次处理到一个对象时,首先著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】会去临时变量里面查找,如果找到的话,会把原创内容,盗版必究。原创内容,盗版必究。这个变量的索引值作为参考系数,直接用于h【关注微信公众号:wwwtangshuangnet】【版权所有,侵权必究】ash计算。
原创内容,盗版必究。原创内容,盗版必究。原创内容,盗版必究。
