Функция копирует объекты в JavaScript, вызывая себя, Нужна помощь в понимании логики - PullRequest
0 голосов
/ 03 июня 2019

Я нашел этот код JavaScript для копирования объектов, код делает то, что должен делать, но я не понимаю, когда функция сама вызывает; почему newObject в первой итерации не теряет своего значения, оно должно быть перезаписано, когда функция вызвала себя и создала новый newObject? Означает ли это, что при вызове самой функции она все еще сохраняет копию первого newObject, созданного до ее вызова?

const o = {
  a: 'a',
  b: 'b',
  obj: {
    key: 'key',
  },
}

const o2 = o

o2.a = 'new value'

// o and o2 reference the same object
console.log(o.a)

// this shallow-copies o into o3
const o3 = Object.assign({}, o)

// deep copy
function deepCopy(obj) {
  // check if vals are objects
  // if so, copy that object (deep copy)
  // else return the value
  const keys = Object.keys(obj)

  const newObject = {}

  for (let i = 0; i < keys.length; i++) {
    const key = keys[i]
    if (typeof obj[key] === 'object') {
      newObject[key] = deepCopy(obj[key])
    } else {
      newObject[key] = obj[key]
    }
  }

  return newObject
}

const o4 = deepCopy(o)

o.obj.key = 'new key!'
console.log(o4.obj.key)

1 Ответ

2 голосов
/ 03 июня 2019

Рекурсивные функции могут сбивать с толку.Несколько хорошо размещенных console.log() s или запуск кода в отладчике могут действительно помочь.Функция создает newObject для исходного объекта и каждого дочернего объекта в объекте .Когда рекурсия раскручивается, она устанавливает свойство в родительском элементе в результате рекурсивного вызова дочернего элемента.

Вы можете увидеть эффект в console.logs здесь:

const o = {
  a: 'a',
  b: 'b',
  obj: {
    key: 'key',
    deeper: {one: 1, two: 2}
  },
}


// deep copy
function deepCopy(obj) {
  console.log("deep copy of: ", obj)
  const keys = Object.keys(obj)

  const newObject = {}

  for (let i = 0; i < keys.length; i++) {
    const key = keys[i]
    if (typeof obj[key] === 'object') {
      console.log("setting child of", key, "to:")
      newObject[key] = deepCopy(obj[key])
    } else {
      newObject[key] = obj[key]
    }
  }

  return newObject
}

console.log("starting with")
const o4 = deepCopy(o)

Каждая из строк, начинающаяся с deep copy of, указывает на вновь созданный newObject в рекурсивном вызове, но единственный возвращаемый newObject - первый - вседругие становятся детьми.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...