为什么这个 Javascript 数据类型(看起来像一个对象)似乎有某种用于识别它的键?
Why does this Javascript data type (which looks like an Object) appear to have a key of some sort for identifying it?
我已经尝试在谷歌上进行了相当广泛的搜索,但是相关的搜索词非常模糊,我什么也没找到。
对象来自第三方库 (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
标识符有关。
- 他们的图书馆需要保留这个标识符,这就是它不起作用的原因,这个理论是否有意义?
- 有没有办法在不丢失标识符的情况下复制对象?
提前致谢。
n
是对象的 class 名称。这很可能是将 myNewObject
传递给第三方库不起作用的原因。该库很可能会使用对象 class 上可用的原型函数之一。
制作对象副本的最佳方法是在可用时使用提供的方法。例如 array.slice()
将创建一个浅表副本,如其文档中所述。
如果 class 没有记录或没有可用的复制方法,您始终可以获取接收到的对象的原型并使用它来创建新对象。然后复制实例属性:
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"
会改变原件,因为你没有改变副本(原件和副本都指向同一个创建者)。有关详细信息,请参阅 link。
// 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));
参考文献:
我已经尝试在谷歌上进行了相当广泛的搜索,但是相关的搜索词非常模糊,我什么也没找到。
对象来自第三方库 (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
标识符有关。
- 他们的图书馆需要保留这个标识符,这就是它不起作用的原因,这个理论是否有意义?
- 有没有办法在不丢失标识符的情况下复制对象?
提前致谢。
n
是对象的 class 名称。这很可能是将 myNewObject
传递给第三方库不起作用的原因。该库很可能会使用对象 class 上可用的原型函数之一。
制作对象副本的最佳方法是在可用时使用提供的方法。例如 array.slice()
将创建一个浅表副本,如其文档中所述。
如果 class 没有记录或没有可用的复制方法,您始终可以获取接收到的对象的原型并使用它来创建新对象。然后复制实例属性:
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"
会改变原件,因为你没有改变副本(原件和副本都指向同一个创建者)。有关详细信息,请参阅 link。
// 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));
参考文献: