JS对象循环引用与JSON序列化。
有这样一段代码,分别表示两个对象的关系,并尝试序列化其中一个:
var objA = {
name: 'this is A'
var objB = {
name: 'this is B'
objA.child = objB
objB.parent = objA
console.log(JSON.stringify(objA))
你会惊讶的发现,得到一个错误:
当你打印出对象objA你会发现:
这个objA就跟愚公一样,头非常的铁,子子孙孙无穷尽也....这就是循环引用了。
怎么消除它呢?怎么中断这种一直循环的引用呢?
首先我们要知道一个东西,叫WeakMap
它的特性是,只能把object当着key来存值,其实就是寸的当前对象的内存地址。例如:
var peo = {
var: 'foo'
var man = peo
var wm = new WeakMap()
wm.set(peo, 'some value')
console.log(wm.has(man), wm.get(man))
所以,有了这个特性,我们可以对循环引用的对象做点判断:
某个属性如果引用了自己的父节点(上一级或者上上一级...),那么这个对象就存在循环引用。
代码如下:
function decycle (target) {
var map = new WeakMap()
function _cycle (obj) {
if (!map.has(obj)) {
map.set(obj, obj)
let keys = Object.keys(obj)
for (let i = 0, len = keys.length; i < len; i++) {
if (typeof obj[keys[i]] === 'object') {
if (map.has(obj[keys[i]])) {
obj[keys[i]] = '$'
continue
} else {
map.set(obj[keys[i]], obj[keys[i]])