为什么改变解构对象中的数字值,也会改变原始对象中的值?

Why changing a Number value in destructured object, change also the value in the original object?

我已经声明了以下对象:

const restaurant = {
  openingHours: {
    thu: {
      open: 12,
      close: 22,
    },
    fri: {
      open: 11,
      close: 23,
    },
    saturday: {
      open: 0, // Open 24 hours
      close: 24,
    },
  }
};

我将 openingHours 对象解构为一个新的变量名 friday:

const { fri: friday } = restaurant.openingHours;

我在星期五对象中修改了开放时间属性的值:

friday.open = 5;

最后我检查了更改是否影响原来的餐厅属性:

console.log(restaurant.openingHours.fri.open, friday.open); // prints 5 5

我不明白为什么要把restaurant.openingHours.fri.open的值改成5?

因为如果我有以下代码:

let originalAge =5;
let newAge = originalAge;
newAge =6;
console.log(originalAge) // will print 5, So what is the difference here?

因为“星期五”是一个对象并作为引用传递,而 originalAge 是原始值(number/string/boolean ...)。

你可以试试这个:

const { fri } = restaurant.openingHours;
const friday = { ...fri };

这将制作星期五的浅表副本(如果所有第一级值都是基元,则将创建一个真实副本)

您已经通过解构运算符提取了对内部对象 fir 的引用。 它仍然引用 openingHours

的内部对象

要取消绑定,您可以使用以下代码段:


const friday = Object.assign({}, restaurant.openingHours.fri);

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign - 详细了解分配方法。

以下解构语法:

const { fri: friday } = restaurant.openingHours;

... 脱糖为:

const friday = restaurant.openingHours.fri;

以上两者都将变量 friday 设置为对对象的引用:

{
  open: 11,
  close: 23,
}

由于上述对象在您的 restaurant.openingHours.fri 对象中也是相同的引用,因此 fridayrestaurant.openingHours.fri 将引用内存中的相同对象。因此,当您这样做时:

friday.open = 5;

您正在更改内存中的一个对象,fridayrestaurant.openingHours.fri 都指向该对象。

但是,在您的示例中,您使用的是按值复制的原语(即:5)。因此它们不会在您的内存中共享(因此更改一个不会更改另一个)。

您可以通过更新解构语法以使用 rest syntax:

来制作 .fri 对象副本的一种方法
const { fri: {...friday} } = restaurant.openingHours;

const restaurant = {
  openingHours: {
    thu: {
      open: 12,
      close: 22,
    },
    fri: {
      open: 11,
      close: 23,
    },
    saturday: {
      open: 0, // Open 24 hours
      close: 24,
    },
  }
};

const { fri: {...friday} } = restaurant.openingHours;
friday.open = 5;
console.log(friday, restaurant.openingHours.fri);