假设我们有以下代码:
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
但是,像在变量的情况下一样,在弱映射中更新值时,我们不改变状态吗?使用需要改写的私人道具时,“最佳做法”是什么?
任何澄清都非常感谢!
要回答关于WeakMaps的问题,我想您是在说副作用。使用WeakMap时,可以想象设置值没有用户区的副作用,因为WeakMaps会反转项目和集合之间的常规关系。在WeakMap中,出于垃圾回收的原因,该项目维护了指向该集合的隐藏链接(而不是该集合维护对该项目的引用),因此我们可以假装没有副作用。
但是,这个问题也与JavaScript的隐私有关。
碰巧的是,JavaScript始终提供了一种出色的机制(据我所知,这是不可穿透的-与C#等语言中的私有字段不同),它提供了强大的隐私保护:闭包。只是大多数开发人员都来自基于类的面向对象背景,并且花时间学习“ JavaScript方式”。
也就是说,在功能开发过程的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和模块也可以使用。有关更多详细信息,请参见下面的链接。
请注意,您也可以使用带有闭包的类,以确保变量保持私有状态。
我不会说更改对象的状态是一种不好的做法,在某些情况下,它是好的,而在某些情况下,它不是。
此外,在某些情况下,如果不更改对象或重新分配变量就无法解决(有些人也建议不要这样做)。
就是这种情况:否则将是不可能的。
现在,回答问题:
更新
WeakMap
中的值是否会更改其状态?
它做更改其状态,但不做对其进行突变(不更改[[properties)。
在这种情况下,这是不好的做法吗?
否!
这样做是完全正确的,并且如果有人说这是一种不好的做法,请考虑:那么还有更好的方法吗?[存储可修改的数据,除非在某些时候修改某些数据。