-1

how can I deep clone an object, what could be wrong with this solution. I wrote this decision, but I'm not sure if this is good, and what bottlenecks it has. How to do it correctly on vanilla js, without using jQuery. If the object has (enumerable: false)?

let user = {
    name: 'SomeName',sayHi: function(){console.log(this.name);}}
Object.defineProperty(user, 'sayHi', {enumerable:false});
function deepCloneNew(obj){
  if (!obj) { return };
  let cloneObj = {};
  let keys = Object.getOwnPropertyNames(obj);
  keys.forEach((key)=>{
    if(typeof obj[key] === 'object' && obj[key] !== null){
        deepCloneNew(obj[key]);
       }
    if(typeof obj[key] === 'function'){ 
      Object.defineProperty(cloneObj, key, Object.getOwnPropertyDescriptor(obj, key));
    }
    if(typeof obj[key] !== 'object' && typeof obj[key] !== 'function' || obj[key] === null){
      Object.defineProperty(cloneObj, key, Object.getOwnPropertyDescriptor(obj, key));
    }
  })
  return cloneObj;
}
let copy = deepCloneNew(user);
  • It is expected that you do a little research before posting a question, a quick google search is surely faster than typing out a whole question and would have brought you up a lot of solutions. Please put a bit more effort in before posting a question next time – Pete Mar 27 '18 at 10:09
  • Cloned object needs to have the same constructor as original as well. – gurvinder372 Mar 27 '18 at 10:11

1 Answers1

0

Please Follow this

function clone(item) {
    if (!item) { return item; } // null, undefined values check

    var types = [ Number, String, Boolean ], 
        result;

    // normalizing primitives if someone did new String('aaa'), or new Number('444');
    types.forEach(function(type) {
        if (item instanceof type) {
            result = type( item );
        }
    });

    if (typeof result == "undefined") {
        if (Object.prototype.toString.call( item ) === "[object Array]") {
            result = [];
            item.forEach(function(child, index, array) { 
                result[index] = clone( child );
            });
        } else if (typeof item == "object") {
            // testing that this is DOM
            if (item.nodeType && typeof item.cloneNode == "function") {
                var result = item.cloneNode( true );    
            } else if (!item.prototype) { // check that this is a literal
                if (item instanceof Date) {
                    result = new Date(item);
                } else {
                    // it is an object literal
                    result = {};
                    for (var i in item) {
                        result[i] = clone( item[i] );
                    }
                }
            } else {
                // depending what you would like here,
                // just keep the reference, or create new object
                if (false && item.constructor) {
                    // would not advice to do that, reason? Read below
                    result = new item.constructor();
                } else {
                    result = item;
                }
            }
        } else {
            result = item;
        }
    }

    return result;
}
Moinul Islam
  • 469
  • 2
  • 9