Это хороший способ клонировать объект в ES6?


Googling для "javascript clone object" приносит некоторые действительно странные результаты, некоторые из них безнадежно устарели, а некоторые просто слишком сложны, не так ли просто:

let clone = {...original};

что-то не так с этим?

4 74

4 ответа:

полностью приемлемо, даже более того, что распространение объекта-это стадия 3. Люди слишком усложняют вещи.

const clone = {...original} клонировать

const newobj = {...original, prop: newOne} чтобы неизменно добавлять другую опору в оригинал и хранить как новый объект.

Объект Использовать.назначить.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

var obj = { a: 1 };
var copy = Object.assign({}, obj);
console.log(copy); // { a: 1 }

однако, это не сделает глубокий клон. До сих пор не существует собственного способа глубокого клонирования.

EDIT: Как упоминалось в комментариях @Mike 'Pomax' Kamermans, вы можете глубоко клонировать простые объекты (т. е. нет прототипов, функций или круговых ссылок) с помощью JSON.parse(JSON.stringify(input))

Если вы не хотите использовать JSON.parse(json.stringify (object)) вы можете создать рекурсивно копии ключ-значение:

function copy(item){
  let result = null;
  if(!item) return result;
  if(Array.isArray(item)){
    result = [];
    item.forEach(element=>{
      result.push(copy(element));
    });
  }
  else if(item instanceof Object && !(item instanceof Function)){ 
    result = {};
    for(let key in item){
      if(key){
        result[key] = copy(item[key]);
      }
    }
  }
  return result || item;
}

но лучший способ-это создать класс, который может вернуть клон IT self

class MyClass{
    data = null;
    constructor(values){ this.data = values }
    toString(){ console.log("MyClass: "+this.data.toString(;) }
    remove(id){ this.data = data.filter(d=>d.id!==id) }
    clone(){ return new MyClass(this.data) }
}
We can do that with two way:
1- First create a new object and replicate the structure of the existing one by iterating 
 over its properties and copying them on the primitive level.

let user = {
     name: "John",
     age: 30
    };

    let clone = {}; // the new empty object

    // let's copy all user properties into it
    for (let key in user) {
      clone[key] = user[key];
    }

    // now clone is a fully independant clone
    clone.name = "Pete"; // changed the data in it

    alert( user.name ); // still John in the original object

2- Second we can use the method Object.assign for that 
    let user = { name: "John" };
    let permissions1 = { canView: true };
    let permissions2 = { canEdit: true };

    // copies all properties from permissions1 and permissions2 into user
    Object.assign(user, permissions1, permissions2);

  -Another example

    let user = {
      name: "John",
      age: 30
    };

    let clone = Object.assign({}, user);
It copies all properties of user into the empty object and returns it. Actually, the same as the loop, but shorter.

Но Объект.назначить () не создавать глубокий клон

let user = {
  name: "John",
  sizes: {
    height: 182,
    width: 50
  }
};

let clone = Object.assign({}, user);

alert( user.sizes === clone.sizes ); // true, same object

// user and clone share sizes
user.sizes.width++;       // change a property from one place
alert(clone.sizes.width); // 51, see the result from the other one

чтобы исправить это, мы должны использовать цикл клонирования, который проверяет каждое значение user[key] и, если это объект, затем реплицирует его структуру. Это называется "глубокое клонирование".

есть стандартный алгоритм глубокого клонирования, который обрабатывает случай, выше, и более сложные случаи, называется структурированной алгоритм клонирования. Чтобы не изобретать велосипед, можно использовать рабочий реализация его из библиотеки JavaScript лодашь метод называется _.cloneDeep (obj).