简体   繁体   中英

Function copies objects in JavaScript by calling itself, Need help understanding the logic

I found this JavaScript code for copying Objects, the code is doing what it's suppose to do, but what I don't understand is when the function call itself; how come newObject in the first iteration desn't loose its value, it should be overwritten when the function called itself and created a new newObject ? does that mean that when a function call itself it still keeps a copy of the first newObject created before it called itself?

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)

Recursive functions can be confusing. A few well placed console.log() s or running the code in a debugger can really help. The function makes a newObject for the original object and each child object in the object . As the recursion unwinds it sets the property in the parent to the result of the recursive call on the child.

You can see the effect in the console.logs here:

 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) 

Each of the lines starting with deep copy of indicates a newly created newObject in a recursive call, but the only newObject returned is the first one — all the others get set as children.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM