生成对象引用的哈希字符串

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

尽管 aab 是不同的对象(尽管相同 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# 中通过使用 pointersaddresses 来实现,但是 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 对象。触发了哪些事件处理程序,或者访问了图中的哪些节点,等等。