使用slice()时数组正在变异

时间:2017-03-14 07:39:45

标签: javascript

Array.prototype.indicesOf = function (el) {
    let indices = [];
    for (var i = this.length - 1; i >= 0; i--) {
        if (this[i] === el)
          indices.unshift(i);
    }
    return indices;
}

class CommentNester {

  constructor(comments) {
    this.comments = comments;
    this.nestedComments = this.nest();
  }

  getComments() {
    return this.comments;
  }

  getNestedComments() {
    return this.nestedComments;
  }

  nest() {

    const comments = this.comments.slice();

    (function appendChildren(parent_id = null) {

      const childIndices = comments.map(comment => comment.parent_id).indicesOf(parent_id);

      childIndices.forEach(index => {
        const child = comments[index];

        if (parent_id) {
          const parentIndex = comments.findIndex(comment => comment.id === parent_id);
          if (!comments[parentIndex].children) {
             comments[parentIndex].children = [];
          }
          comments[parentIndex].children.push(child);
        }

        appendChildren(child.id);
      });

    })();

    return comments.filter(comment => comment.parent_id === null);
  }

}

const comments = [{
  id: 1,
  text: "Top level",
  parent_id: null
}, {
  id: 2,
  text: "Top level",
  parent_id: null
}, {
  id: 3,
  text: "Reply level 1",
  parent_id: 1
}, {
  id: 4,
  text: "Reply level 1",
  parent_id: 2
}, {
  id: 5,
  text: "Reply level 2",
  parent_id: 3
}];

getComments()显示原始comments数组已变异(它有children),但我希望它保持原始状态。我使用.slice()创建副本,但由于某种原因,它仍然会发生变异。有什么想法吗?

Codepen:http://codepen.io/anon/pen/QpMWNJ?editors=1010

2 个答案:

答案 0 :(得分:0)

使用对象映射,

const comments = this.comments.slice()
const cloneComments = comments.map(f => {
        let o = {}
        for(var i in f) o[i] = f[i]
        return o
    })

答案 1 :(得分:0)

你的答案应该在这里 - What is the most efficient way to deep clone an object in JavaScript?

如果您想避免使用jQuery,请转到JSON.parse(JSON.stringify(obj))解决方案const comments = JSON.parse(JSON.stringify(this.comments));

注意:如果存在循环依赖

,这将会中断

如果您可以使用jQuery,请使用extend

进行更清洁的方法
// Deep copy
var newObject = jQuery.extend(true, {}, oldObject);