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]])