【问题标题】:Using Javascript .find() seems to be doing some weird coercion I can't seem to pinpoint [duplicate]使用 Javascript .find() 似乎做了一些奇怪的强制,我似乎无法确定 [重复]
【发布时间】:2020-04-12 08:39:56
【问题描述】:

我正在尝试从DATA 收集所有对象并与schemesFromPOI 进行比较。如果名称是 AMERICAN_EXPRESS,我只想在 scheme 对象中将其更改为 AMEX,保留 DATA 对象。

const DATA =
    [
      {
        "name": "MASTERCARD",
        "id": "MASTERCARD123"
      },
      {
        "name": "VISA",
        "id": "VISA456"
      },
      {
        "name": "AMERICAN_EXPRESS",
        "id": "AMEX789"
      }
    ];

const schemesFromPOI = [
  { dpaId: 'DPA1', name: 'MASTERCARD' },
  { dpaId: 'DPA2', name: 'VISA' },
  { name: 'AMERICAN_EXPRESS' }
];

let config = [];

schemesFromPOI.forEach(function (schemeFromPOI) {

  let scheme = DATA.find(function (element) { return element.name === schemeFromPOI.name; });

  if(scheme) {
    if (scheme.name === "AMERICAN_EXPRESS") {
      console.log("Before updating scheme.name property: ", DATA);
      scheme.name = 'AMEX';
      console.log("After updating scheme.name property: ", DATA);
    }

    config.push(scheme);
  }

});

但是,当我更改 scheme.name 时,DATA 对象也会更新。以下是上述控制台输出的结果:

Before updating scheme.name property: "[{'name':'MASTERCARD','id':'MASTERCARD123'},{'name':'VISA','id':'VISA456'},{'name':'AMERICAN_EXPRESS','id':'AMEX789'}]"
After updating scheme.name property: "[{'name':'MASTERCARD','id':'MASTERCARD123'},{'name':'VISA','id':'VISA456'},{'name':'AMEX','id':'AMEX789'}]"

显然DATA 对象正在更新,而不仅仅是scheme 对象。为什么会发生这种强制?和.find()方法有关系吗?

【问题讨论】:

标签: javascript arrays javascript-objects


【解决方案1】:

这是因为数组是引用类型。所以当你编辑scheme.name = 'AMEX';时,这意味着scheme.name将被改变,并且在DATA中找到一个对象。

如果你想创建一个全新的对象,那么使用传播... 运算符:

const data = [
    { name: "John", age: "22", weight: "60", height: "180cm" },
    { name: "Emma", age: "25", weight: "55", height: "160cm" }
];

let obj = data.find(f=> f.name =='John');

let brandNewObject = {...obj};

一个例子:

const data = [
        { name: "John", age: "22", weight: "60", height: "180cm" },
        { name: "Emma", age: "25", weight: "55", height: "160cm" }
    ];
    
    let obj = data.find(f=> f.name =='John');        
    let brandNewObject = {...obj};        
    brandNewObject .name = "Joseph";
    
    console.log(`obj`, obj);
    console.log(`brandNewObject `, brandNewObject );

【讨论】:

  • 这行得通!但是 IE 不支持扩展运算符,不幸的是我必须支持它。有解决办法吗?
  • 在 IE polyfill 中使用 let scheme = Object.assign({}, obj); 而不是扩展运算符对我来说是一个很好的解决方法。
【解决方案2】:

这发生在 JS 中,我们称之为 Mutable 类型,您可以访问此链接以更好地理解 https://developer.mozilla.org/en-US/docs/Glossary/Mutable

回到你的答案

Object.freeze(DATA);

上面的代码将冻结对象并且不允许它被更新。

【讨论】:

  • 这在这种情况下似乎不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2014-04-20
  • 2015-11-11
相关资源
最近更新 更多