假设我们有以下代码:
const _timeStamp = new WeakMap();
const _running = new WeakMap();
export class Stopwatch {
constructor() {
_timeStamp.set(this, 0);
_running.set(this, false);
}
start() {
// start stopwatch
_running.set(this, true)
_timeStamp.set(this, Date.now())
}
stop() {
// stop stopwatch
_running.set(this, false);
return (Date.now() - _timeStamp.get(this))/1000
}
}
在此示例中,我们尝试使用弱映射向最终用户隐藏一些信息。 根据调用的方法,我们更改两个弱映射中的值。 当我们重新分配变量时,我们会改变状态。
let x = 0;
x = 10
编辑:
但是,在更新弱映射中的值时,我们是否会像处理变量一样改变状态?使用需要可重写的私有(private)属性时,“最佳实践”是什么?
非常感谢任何澄清!
最佳答案
回答您关于 WeakMaps 的问题,我认为你在谈论副作用。使用 WeakMap 时,您可以想象设置值不会对用户产生副作用,因为 WeakMap 反转了项目和集合之间的通常关系。在 WeakMap 中,由于垃圾回收的原因,该项目维护了一个到该集合的隐藏链接(而不是该集合维护对该项目的引用),因此我们可以假装没有副作用。
但是,这个问题也与 JavaScript 中的隐私有(private)关。
事实上,JavaScript 始终提供了一种出色的(据我所知也是难以理解的 - 与 C# 等语言中的私有(private)字段不同)机制来实现稳健的隐私:闭包。只是大多数开发人员都来自基于类的面向对象背景,需要花时间学习“JavaScript 方式”。
也就是说,将类上的字段标记为私有(private)的语法目前位于 Stage 3功能开发过程的一部分,并由转译器支持。
所以答案是:有多种方法可以确保隐私,具体取决于具体的用例和您的团队使用的代码风格。
使用类的团队可能会使用# private class field syntax 。
class MyClass {
#myPrivateField = 'foo'
bar(s) {
return this.#myPrivateField + s
}
}
使用函数的团队将使用closures 。
function createObject() {
let myPrivateVariable = 'foo'
return {
bar(s) {
return myPrivateField + s
}
}
}
您可以对此进行挑剔,并说 bar
的函数对象是在每个实例的基础上创建的。在绝大多数情况下,这并不重要。
Symbols有时会被使用,尽管它们提供的隐私性较低,因为它们可以通过反射查看。
function createObject() {
let secretSymbol = Symbol('secret')
return ({
[secretSymbol]: 'foo',
bar(s) {
return this[secretSymbol] + s
}
})
}
WeakMaps也可以使用模块。有关更多详细信息,请参阅下面的链接。
请注意,您还可以使用带有闭包的类来确保变量保持私有(private)。
关于javascript - 在weakmaps中设置新值时我们会改变状态吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60340487/