生成对象引用的哈希字符串
Generate a hash string of an object's reference
我想生成从 Object
的引用派生的散列,然后将散列字符串与对象本身关联到字典中。
我听说过 object-hash 并尝试了以下实现:
const objectHash = require('object-hash');
class A {
a: string;
constructor() {
this.a = '1';
}
}
let a = new A();
let ab = new A();
console.log(objectHash(a)); // 712041d72943c4794bb23d1d455e17b3a4ea17f5
console.log(objectHash(ab));// 712041d72943c4794bb23d1d455e17b3a4ea17f5
尽管 a
和 ab
是不同的对象(尽管相同 class 的实例),但生成的哈希值是相等的,这不是预期的结果。这是因为库散列 对象值 而不是 对象引用 .
预期结果
let foo = new A();
let bar = new A();
const fooH = objectHash(foo); <-- Produces a unique hash string representing the reference of "foo"
const barH = objectHash(bar); <-- Produces a unique hash string representing the reference of "bar"
let objects = {
fooH: foo,
barH: bar
}
这可能在 C++ 或 C# 中通过使用 pointers 和 addresses 来实现,但是 Javascript 呢?
如果有人能指导我正确地将对象的引用封装到字符串中,将不胜感激。
无法在 JavaScript 中获取对象的引用以计算它的哈希值。引用是引擎的内部值,通常不会公开。
但是,如果您想针对某个对象索引某些数据,您可以使用 Map
,因为键可以是任意 JavaScript 值,因此允许对象。由于对象在比较过程中是唯一的,这意味着相同的对象 returns 值:
class A {
constructor() {
this.a = '1';
}
}
const foo = new A();
const bar = new A();
const map = new Map()
.set(foo, "hello")
.set(bar, "world");
console.log(map.get(foo), map.get(bar));
JavaScript 也有一个 WeakMap
- 它只允许对象作为键,但反过来它只持有对它们的弱引用。这意味着一旦对键的任何其他引用消失,WeakMap
将不会阻止对象被垃圾收集。
映射,尤其是 WeakMap,是 扩展 外来对象的可行方法,而无需实际将它们嵌套在您自己的层次结构中。这是一个快速演示
import {a, b} from 'foreign';
const extension = new WeakMap()
extension.set(a, {
myProperty1: true,
myProperty2: 40,
myProperty3: "hello",
});
extension.set(b, {
myProperty1: false,
myProperty2: 2,
myProperty3: "world"
});
这里我们得到了一些外国对象a
,并且b
我们不需要控制和扩展它们与我们自己的属性,而无需更改 或 克隆 它们。查看 WeakMap
中的对象可提供扩展属性。
见 by Benjamin Gruenbaum
为了进一步参考,Set
and a WeakSet
在存储对象方面分别表现出与 Map 和 WeakMap 相同的属性。但是,它们没有为对象提供额外的价值。这可能很有用,例如,跟踪 seen 对象。触发了哪些事件处理程序,或者访问了图中的哪些节点,等等。
我想生成从 Object
的引用派生的散列,然后将散列字符串与对象本身关联到字典中。
我听说过 object-hash 并尝试了以下实现:
const objectHash = require('object-hash');
class A {
a: string;
constructor() {
this.a = '1';
}
}
let a = new A();
let ab = new A();
console.log(objectHash(a)); // 712041d72943c4794bb23d1d455e17b3a4ea17f5
console.log(objectHash(ab));// 712041d72943c4794bb23d1d455e17b3a4ea17f5
尽管 a
和 ab
是不同的对象(尽管相同 class 的实例),但生成的哈希值是相等的,这不是预期的结果。这是因为库散列 对象值 而不是 对象引用 .
预期结果
let foo = new A();
let bar = new A();
const fooH = objectHash(foo); <-- Produces a unique hash string representing the reference of "foo"
const barH = objectHash(bar); <-- Produces a unique hash string representing the reference of "bar"
let objects = {
fooH: foo,
barH: bar
}
这可能在 C++ 或 C# 中通过使用 pointers 和 addresses 来实现,但是 Javascript 呢? 如果有人能指导我正确地将对象的引用封装到字符串中,将不胜感激。
无法在 JavaScript 中获取对象的引用以计算它的哈希值。引用是引擎的内部值,通常不会公开。
但是,如果您想针对某个对象索引某些数据,您可以使用 Map
,因为键可以是任意 JavaScript 值,因此允许对象。由于对象在比较过程中是唯一的,这意味着相同的对象 returns 值:
class A {
constructor() {
this.a = '1';
}
}
const foo = new A();
const bar = new A();
const map = new Map()
.set(foo, "hello")
.set(bar, "world");
console.log(map.get(foo), map.get(bar));
JavaScript 也有一个 WeakMap
- 它只允许对象作为键,但反过来它只持有对它们的弱引用。这意味着一旦对键的任何其他引用消失,WeakMap
将不会阻止对象被垃圾收集。
映射,尤其是 WeakMap,是 扩展 外来对象的可行方法,而无需实际将它们嵌套在您自己的层次结构中。这是一个快速演示
import {a, b} from 'foreign';
const extension = new WeakMap()
extension.set(a, {
myProperty1: true,
myProperty2: 40,
myProperty3: "hello",
});
extension.set(b, {
myProperty1: false,
myProperty2: 2,
myProperty3: "world"
});
这里我们得到了一些外国对象a
,并且b
我们不需要控制和扩展它们与我们自己的属性,而无需更改 或 克隆 它们。查看 WeakMap
中的对象可提供扩展属性。
见
为了进一步参考,Set
and a WeakSet
在存储对象方面分别表现出与 Map 和 WeakMap 相同的属性。但是,它们没有为对象提供额外的价值。这可能很有用,例如,跟踪 seen 对象。触发了哪些事件处理程序,或者访问了图中的哪些节点,等等。