为什么此Javascript数据类型看起来像对象看起来具有某种用于识别它的键?

问题描述

我已经尝试过广泛地使用Google搜索,但是相关的搜索字词非常模糊,因此我什么也找不到。

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

以下是一些假设的代码

const myObject = thirdPartyLibrary.getMyObject();

如果我进行console.log(myObject),我会在我的Chrome DevTools中看到它:

code screenshot

它看起来像一个对象,但是具有这个n键,看起来像是一个标识符。

当我尝试复制它时,就像这样:

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

后执行console.log(myNewObject),我看到了:

enter image description here

相同,但没有n标识符。

将此新的n较少的对象传递回第三方库提供的方法不起作用,而使用原始对象则起作用。我必须假定它与该n标识符有关。

  1. 该理论是否有意义,他们的库将需要保留此标识符,这就是为什么它不起作用的原因?
  2. 有没有一种方法可以复制对象而不丢失该标识符?

谢谢。

解决方法

Like already stated in the comments 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仍然是shallow 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));

参考: