0

假设我们有以下代码:

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

编辑:


作为最佳实践,我们不应该在 JS 中改变对象或更改状态

但是,在更新弱图中的值时,我们不会像在变量的情况下那样改变状态吗?使用需要可重写的私有道具时,“最佳实践”是什么?

任何澄清都非常感谢!

4

1 回答 1

1

要回答您关于WeakMaps的问题,我认为您在谈论副作用。使用 Wea​​kMap 时,您可以想象设置值没有用户空间副作用,因为 WeakMaps 反转了项目和集合之间的通常关系。在 WeakMap 中,出于垃圾回收的原因,项目维护到集合的隐藏链接(而不是集合维护对项目的引用),因此我们可以假装没有副作用。

但是,这个问题也与 JavaScript 中的隐私有关。

碰巧的是,JavaScript 始终提供了一种出色的(据我所知是难以理解的 - 与 C# 等语言中的私有字段不同)强大的隐私机制:闭包。只是大多数开发人员来自基于类的面向对象背景,需要花时间学习“JavaScript 方式”。

也就是说,将类上的字段标记为私有的语法目前处于功能开发过程的第 3 阶段,并由转译器支持。

所以答案是:有多种方法可以确保隐私,具体取决于具体的用例和团队使用的代码风格。

使用类的团队可能会使用#private class field syntax

class MyClass {
   #myPrivateField = 'foo'
   bar(s) {
       return this.#myPrivateField + s
   }
}

使用函数的团队将使用闭包

function createObject() {
    let myPrivateVariable = 'foo'
    return {
        bar(s) {
            return myPrivateField + s
        }
    }
}

您可以挑剔这个并说函数对象bar是基于每个实例创建的。在绝大多数情况下,这无关紧要。

有时会使用符号,尽管它们提供的隐私较少,因为它们可以通过反射来查看。

function createObject() {    
    let secretSymbol = Symbol('secret')
    return ({
        [secretSymbol]: 'foo',
        bar(s) {
            return this[secretSymbol] + s
        }
    })
}

WeakMaps和模块也可以使用。有关更多详细信息,请参阅下面的链接。

请注意,您还可以使用带有闭包的类来确保变量保持私有。

另请参阅

于 2020-02-21T15:27:32.853 回答