获取一个对象的hash值

广告位招租
扫码页面底部二维码联系

我们比较两个对象,比较好的一种办法是直接【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.net比较两个对象的hash值,对于相同结构和【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。内容的对象,hash值应该相等。怎么获取著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。对象的hash值?

【原创不易,请尊重版权】【未经授权禁止转载】【原创不易,请尊重版权】【作者:唐霜】【原创内容,转载请注明出处】
/**
 * 获取一个字符串的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
}

这里面考虑到了一个非常严重的问题,就是当转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。一个对象如果存在自引用的情况,普通的遍历【本文受版权保护】【版权所有,侵权必究】会引起死循环而导致程序挂掉,但这个函数不【原创内容,转载请注明出处】【本文首发于唐霜的博客】会,它会用一个临时变量去记录已经处理过的未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。对象,如果在下一次处理到一个对象时,首先【本文受版权保护】著作权归作者所有,禁止商业用途转载。会去临时变量里面查找,如果找到的话,会把本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。这个变量的索引值作为参考系数,直接用于h【原创不易,请尊重版权】【原创不易,请尊重版权】ash计算。

原创内容,盗版必究。【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net