简体   繁体   English

JavaScript object 解构的问题

[英]Problems with JavaScript object destructuring

 let pppp = { name: "duanxiao", age: 1, job: { title: "~~~" } }; let ppppCopy = {}; ({ name: ppppCopy.name, age: ppppCopy.age, job: ppppCopy.job } = pppp); pppp.job.title = "Hacker"; console.log(pppp); console.log(ppppCopy);

The output values are the same. output 值相同。

Why modifying the value of one object, the other object will also be modified?为什么修改一个object的值,另一个object也会被修改?

Whenever I modify the value of one object, the value of the other object is also modified.每当我修改一个object的值时,另一个object的值也被修改。

In JS, and many other languages, you have data types that store by value, like Number and other primitive types.在 JS 和许多其他语言中,您有按值存储的数据类型,如 Number 和其他基本类型。 Some data types stored by reference, like Arrays, Object.一些数据类型通过引用存储,如 Arrays、Object。

By destructing pppp you just passing the reference to the inner job object, and not duplicating it, so technically its the same job object in pppp and ppppCopy .通过破坏pppp ,您只是传递了对内部job object 的引用,而不是复制它,因此从技术上讲,它是ppppppppCopy中的相同job object。

Here I added a manipulation to a primitive, and you can see that there is a difference.这里我对一个原语添加了一个操作,你可以看到有区别。

 let pppp = { name: "duanxiao", age: 1, job: { title: "~~~" } }; let ppppCopy = {}; ({ name: ppppCopy.name, age: ppppCopy.age, job: ppppCopy.job } = pppp); pppp.job.title = "Hacker"; pppp.age = 123; console.log(pppp); console.log(ppppCopy);

Here is another good answer related 这是另一个相关的好答案

Because you pppp and ppppCopy holds the same reference of job property.因为您ppppppppCopy持有相同的job属性引用。 Changing at one location will impact another.在一个位置更改会影响另一个位置。 You can achieve your intended outcome with below code using ES6 spread operator,您可以使用 ES6 传播运算符通过以下代码实现预期结果,

let pppp = {
    name: "duanxiao",
    age: 1,
    job: {
        title: "~~~"
    }
};

const ppppCopy = {
  ...pppp,
  job: { ...pppp.job },
};

With this, updating pppp.job.title will not impact ppppCopy.job.title .这样,更新pppp.job.title将不会影响ppppCopy.job.title

You can also use the traditional way like JSON.parse(JSON.stringify(pppp)) , but you need to be more cautious while using this approach as it strips down the function property您也可以使用像JSON.parse(JSON.stringify(pppp))这样的传统方式,但是在使用这种方法时您需要更加谨慎,因为它会剥离 function 属性

The only way is to use JSON.parse(JSON.stringify(pppp));唯一的方法是使用 JSON.parse(JSON.stringify(pppp));

    name: "duanxiao",
    age: 1,
    job: {
        title: "~~~"
    }
};
let ppppCopy = JSON.parse(JSON.stringify(pppp));



pppp.job.title = "Hacker";

console.log(pppp);
console.log(ppppCopy);

Since objects are non-primitive data types javascript makes a reference of the original object when you make a copy using the assignment operator as you have done in your case.由于对象是非原始数据类型 javascript 当您使用赋值运算符制作副本时, javascript 会引用原始数据 object ,就像您在案例中所做的那样。 In order to avoid shallow copying you can use the spread operator ie let copy = {...original} or you can use the assign method ie let copy = Object.assign({}, original) but both of these fail when you have a nested object. In order to deep copy a nested object you need to do it as Edoardo pointed out above but that will fail too when there is a function in your object. Ravindra's method can also be used, but it will be a hassle when you have multiple nested objects.为了避免浅复制,您可以使用扩展运算符,即let copy = {...original}或者您可以使用分配方法,即let copy = Object.assign({}, original)但是当您有一个嵌套的 object。为了深度复制一个嵌套的 object,你需要按照 Edoardo 上面指出的那样去做,但是当你的 object 中有一个 function 时,这也会失败。也可以使用 Ravindra 的方法,但是当你有多个嵌套对象。

The best way to do it in my opinion is to use lodash _.cloneDeep() method.我认为最好的方法是使用 lodash _.cloneDeep()方法。 You can read more about it here你可以在这里阅读更多相关信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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