假设你想比较两个javascript对象或数组以获得引用相等。
最明显的解决方案是
if (a === b) { /*...*/ };
这个问题是a
和b
必须保存对实际对象的引用。在同样的情况下,这可能是个问题。例如,尝试在memoization函数中保存实际引用会产生内存泄漏。
一种方法是使用JSON.stringify(a)
来获取对象的字符串表示并进行比较。但在某些使用案例中,这可能会非常昂贵。更不用说实际的参考平等没有被考虑在内。
这让我感到疑惑。有没有办法对实际引用进行字符串化而不是对象内容?显然,你不能在javascript中操作指针,但是如果你只能得到某种指针表示怎么办呢。一个哈希值?原始内存位置? Guid或整数表示?
我知道在chrome dev工具中分析内存转储时会有一些对象id-s。也许这些东西可以在运行时访问?在node.js中使用某种特殊的开关?
有人能想到一种在javascript中完成这项工作的方法吗?
答案 0 :(得分:3)
如果要将其用于记忆(缓存),则应使用ES6 WeakMap
。它适用于Firefox 6,Chrome 36和IE 11。
WeakMap对象是键/值对的集合,其中键是对象,值可以是任意值。 [...] 经验丰富的JavaScript程序员会注意到,这个API可以用JavaScript实现,它有四个API方法共享的两个数组(一个用于键,一个用于值)。这样的实施将有两个主要的不便之处。第一个是O(n)搜索(n是地图中的键数)。第二个是内存泄漏问题。
它的工作方式类似于Java中的地图 - 您可以将任意对象用作键和值。但是密钥不会阻止垃圾收集,所以你不必担心内存泄漏,但仍然可以找到给定对象的记忆计算。
答案 1 :(得分:0)
受到@ user2864740评论的启发(老兄,设置一个名字,严肃地说: - ))。
它也可能只是参与此系统的对象的必需方法
此实现扩展了Object prototype以包含一个实用程序,以便为每个对象生成唯一的UUID。 generateId
的实施取自here。
似乎正在为对象和数组工作。
Object.prototype._id = function () {
return this.__id || (this.__id = generateId());
function generateId() {
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
}
}
function assert(message, test) {
if (!test) {
throw new Error("ASSERTION FAILED: " + message);
} else {
console.log("PASSED: " + message);
}
}
var x = { name: "same" },
y = { name: "same" },
z = [],
x2 = x;
assert("Id is unchanging", x._id() === x._id());
assert("Id is different for different objects", x._id() !== y._id());
assert("Arrays have id too", z._id() === z._id());
assert("Id is same for same objects", x._id() === x2._id());
我离开这里,看看是否有问题,或者是否有人有更好的主意。