// DO NOT USE this implementation or anything like it
const BAD_objectId = (() => {
'use strict';
// const objIdKey = Symbol(); would have been only marginally better
const objIdKey = '__OBJECT_ID_DO_NOT_USE_OR_YOU_WILL_BE_FIRED';
let counter = 0n;
return obj => {
let ident = obj[objIdKey];
if (ident === void 0) {
ident = counter++;
obj[objIdKey] = ident;
}
return ident;
};
})();
{
const o = {};
const op = new Proxy(o, {});
console.log(
`an object is #${BAD_objectId(o)}`);
console.log(
`a proxy is also #${BAD_objectId(op)}`);
const oc = { ...o };
console.log(
`an object copy is also #${BAD_objectId(oc)}`);
}
try {
const o = Object.freeze({});
console.log(
`a frozen object is #${BAD_objectId(o)}`);
console.log(
`the same frozen object is #${BAD_objectId(o)}`);
} catch (e) {
console.warn(`${e}`);
}
document.body.dataset.a = 123;
console.log(
`document.body.dataset is #${BAD_objectId(document.body.dataset)}`);
console.log(`dataset contains`, document.body.dataset);
console.log(
`Object.prototype is #${BAD_objectId(Object.prototype)}`);
console.log(
`a fresh object is also #${BAD_objectId({})}`);
console.log(
`another fresh object is also #${BAD_objectId({})}`);
const m = new Map();
// then for each object
if (m.has(object)) {
console.log('already seen this', m.get(object), 'times');
m.set(object, m.get(object) + 1);
} else {
m.set(object, 1);
}
2条答案
按热度按时间hl0ma9xz1#
标准ECMAScript不会公开任何返回唯一对象标识符的接口,似乎也没有任何特定于Node.js的API。但是,您可以使用
WeakMap
自己分配唯一ID:字符串
这将在遇到对象时为它们分配连续的整数。在实现Symbols as WeakMap keys proposal的引擎中,它还将为符号分配标识符,您可能需要也可能不需要:如果要过滤掉它们,请使用
typeof
运算符。(如果您 * 确实 * 想要为符号分配标识符,即使在没有实现该建议的引擎中,您也可以回退到Map
,但要注意,这些符号将被有效地泄漏。仅将其用作 transient 调试辅助工具。)如果你真的想做得更好,你可以使用
FinalizationRegistry
来回收已经被垃圾收集的对象的ID。但是我建议不要这样做,因为如果你最终获得了一些对象的ID,收集了这些对象,然后重新分配了这些ID,并错误地将僵尸ID视为引用新对象,那么它可能会导致混乱。在其他地方,你可能会遇到其他的解决方案:寄生属性,无论是字符串还是符号键,都不会对不可扩展的对象起作用,可能会改变在其他地方可观察到的对象的状态,无法区分代理和目标,并且经常获得
Object.prototype
的ID足以完全破坏系统。避免这些。参见下面的原因:型
1rhkuytd2#
没有任何内置的东西,但是你可以使用
Map
对象索引来检查它。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
字符串