var obj1 = {
	  a: {
        a1: { a2: 1 },
        a10: { a11: 123, a111: { a1111: 123123 } }
      },
      b: 123,
      c: "123"
}
function clone1(o) {
	let obj = {}
	for (let i in o) {
		obj[i] = o[i]
	}
	
	return obj
}
var cloneObj2 = {...obj1}
var cloneObj3 = Object.assign({}, obj1)
function deepClone1(o) {
	let obj = {}
	for (var in o) {
		if(typeof o[i] === "object") {
			obj[i] = deepClone(o[i])
		} else {
			obj[i] = o[i]
		}
	} 
	return obj
}
function deepClone2(o) {
      if (Object.prototype.toString.call(o) === "[object Object]"){
        let obj = {}
        for (var i in o) {
          if (o.hasOwnProperty(i)) {
            if (typeof o[i] === "object") {
              obj[i] = deepClone(o[i])
            } else {
              obj[i] = o[i]
            }
          }
        }
        return obj
      } else {
        return o
      }
    }
    function isObject(o) {
      return Object.prototype.toString.call(o) === "[object Object]" || Object.prototype.toString.call(o) === "[object Array]"
    }
    
    function deepClone3(o) {
      if (isObject(o)) {
        let obj = Array.isArray(o) ? [] : {}
        for (let i in o) {
          if (isObject(o[i])) {
            obj[i] = deepClone(o[i])
          } else {
            obj[i] = o[i]
          }
        }
        return obj
      } else {
        return o
      }
    }
    
    
    
function deepClone4(o,hash = new map()) {
	if (!isObject(o)) return o;
	if (hash.has(o)) return hash.get(o)
	
	let obj = Array.isArray(o) ? []: {}
	hash.set(o,obj)
	for (let i in o) {
		if(isObject(o[i])) {
			obj[i] = deepClone4(o[i],hash)
		} else {
			obj[i] = o[i]
		}
	}
	return obj
}
    
    
    var a1 = { a: 1, b: 2, c: { c1: 3, c2: { c21: 4, c22: 5 } }, d: 'asd' };
    var b1 = { b: { c: { d: 1 } } }
    function cloneLoop(x) {
      const root = {};
      
      const loopList = [  
        {
          parent: root,
          key: undefined,
          data: x,
        }
      ];
      while (loopList.length) {
        
        const node = loopList.pop();
        const parent = node.parent; 
        const key = node.key; 
        const data = node.data; 
        
        let res = parent; 
        if (typeof key !== 'undefined') {
          res = parent[key] = {};
        }
        for (let k in data) {
          if (data.hasOwnProperty(k)) {
            if (typeof data[k] === 'object') {
              
              loopList.push({
                parent: res,
                key: k,
                data: data[k],
              })
            } else {
              res[k] = data[k];
            }
          }
        }
      }
      return root
    }
    function deepClone5(o) {
      let result = {}
      let loopList = [
        {
          parent: result,
          key: undefined,
          data: o
        }
      ]
      while (loopList.length) {
        let node = loopList.pop()
        let { parent, key, data } = node
        let anoPar = parent
        if (typeof key !== 'undefined') {
          anoPar = parent[key] = {}
        }
        for (let i in data) {
          if (typeof data[i] === 'object') {
            loopList.push({
              parent: anoPar,
              key: i,
              data: data[i]
            })
          } else {
            anoPar[i] = data[i]
          }
        }
      }
      return result
    }
    let cloneA1 = deepClone5(a1)
    cloneA1.c.c2.c22 = 5555555
    console.log(a1);
    console.log(cloneA1);
    
    function cloneJson(o) {
      return JSON.parse(JSON.stringify(o))
    }