这是一个非常难的问题。老实说,我对 JavaScript 的上下文一无所知,所以我在 esdiscuss 中询问并从Domenic那里得到了令人信服的答案。
出于安全和验证原因,WeakSets 很有用。如果你希望能够隔离一段 JavaScript。它们允许您标记对象以表明它属于一组特殊的对象。
假设我有一堂课ApiRequest
:
class ApiRequest {
constructor() {
// bring object to a consistent state, use platform code you have no direct access to
}
makeRequest() {
// do work
}
}
现在,我正在编写一个 JavaScript 平台——我的平台允许你运行 JavaScript 来进行调用——进行那些你需要的调用 a——ApiRequest
我只希望你ApiRequest
使用我给你的对象进行 s,这样你就不能绕过任何约束我已经到位。
但是,目前没有什么能阻止您这样做:
ApiRequest.prototype.makeRequest.call(null, args); // make request as function
Object.create(ApiRequest.prototype).makeRequest(); // no initialization
function Foo(){}; Foo.prototype = ApiRequest.prototype; new Foo().makeRequest(); // no super
依此类推,请注意,您不能保留普通的ApiRequest
对象列表或数组,因为这会阻止它们被垃圾收集。除了闭包之外,任何事情都可以通过诸如Object.getOwnPropertyNames
or之类的公共方法来实现Object.getOwnSymbols
。所以你和我一起做:
const requests = new WeakSet();
class ApiRequest {
constructor() {
requests.add(this);
}
makeRequest() {
if(!request.has(this)) throw new Error("Invalid access");
// do work
}
}
现在,无论我做什么——我必须持有一个有效的ApiRequest
对象来调用makeRequest
它的方法。如果没有 WeakMap/WeakSet,这是不可能的。
所以简而言之 - WeakMaps 对于用 JavaScript 编写平台很有用。通常这种验证是在 C++ 端完成的,但添加这些功能将启用 JavaScript 中的移动和制作。
(当然,将值映射到的所有 aWeakSet
都可以执行,但对于任何 map/set 构造都是如此)WeakMap
true
(就像 Bergi 的回答所暗示的,没有理由直接将对象文字添加到 aWeakMap
或 a WeakSet
)