首页 > 解决方案 > 为什么这种 Javascript 数据类型(看起来像一个对象)似乎有某种用于识别它的键?

问题描述

我已经尝试过广泛使用谷歌搜索,但是相关的搜索词非常模糊,我什么也没找到。

该对象来自第三方库 (Jibestream)。

这是一些假设的代码:

const myObject = thirdPartyLibrary.getMyObject();

如果我这样做console.log(myObject)了,我会在我的 Chrome DevTools 中看到:

代码截图

它看起来像一个对象,但这个n键似乎是某个标识符。

当我尝试复制它时,如下所示:

const newWaypointsArray = getNewWaypoints();
const myNewObject = { ...myObject, waypoints: newWaypointsArray };

然后做console.log(myNewObject),我看到了:

在此处输入图像描述

这是相同的,但没有n标识符。

将这个新的n-less 对象传回第三方库提供的方法是行不通的,而使用原始对象确实有效。我必须假设它与该n标识符有关。

  1. 这个理论是否有意义,他们的图书馆需要保留这个标识符,这就是它不起作用的原因吗?
  2. 有没有办法在不丢失该标识符的情况下复制对象?

提前致谢。

标签: javascriptgoogle-chrome-devtools

解决方案


就像评论中已经说明的那样, n是对象的类名。这很可能是传递myNewObject给第三方库不起作用的原因。该库很可能会使用对象类中可用的原型函数之一。

制作对象副本的最佳方法是在可用时使用提供的方法。例如array.slice(),将创建一个浅拷贝,如其文档中所述。

如果该类未记录或没有可用的复制方法,您始终可以获取接收到的对象的原型并使用它来创建新对象。然后复制实例属性:

const myObject = thirdPartyLibrary.getMyObject();

// create an object using the same prototype
const copy = Object.create(Object.getPrototypeOf(myObject));
// copy over properties
Object.defineProperties(copy, Object.getOwnPropertyDescriptors(myObject));

创建副本后,您可以在不影响原始对象的情况下自由更新其属性。请注意,这copy仍然是浅拷贝。所以改变postCopy.creator.username = "something_else"会改变原件,因为你没有改变副本(原件和副本都指向同一个创建者)。有关更多信息,请参阅链接。

// mock
class Person {
  constructor(name) {
    this.name = name;
  }
  greet() {
    return `hello ${this.name}`;
  }
}

const thirdPartyLibrary = {
  getMyObject() {
    return new Person("John Doe");
  },
  useMyObject(person) {
    return person.greet();
  },
};

// answer
const myObject = thirdPartyLibrary.getMyObject();

const copy1 = {...myObject}; // your current attempt
try {
  console.log("copy1:", thirdPartyLibrary.useMyObject(copy1));
} catch (error) {
  console.log("copy1:", error.message);
}

const copy2 = Object.create(Object.getPrototypeOf(myObject));
Object.defineProperties(copy2, Object.getOwnPropertyDescriptors(myObject));

console.log("copy2:", thirdPartyLibrary.useMyObject(copy2));

参考:


推荐阅读