深度克隆对象(JS)

时间:2018-03-27 09:57:08

标签: javascript object

如何深度克隆对象,这个解决方案可能出错。 我写了这个决定,但我不确定这是否好,以及它有什么瓶颈。 如何在vanilla js上正确地完成它,而不使用jQuery。如果对象有(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);

1 个答案:

答案 0 :(得分:0)

请关注

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;
}