javascript - 在weakmaps中设置新值时我们会改变状态吗?

标签 javascript oop javascript-objects es6-class weakmap

假设我们有以下代码:

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 中改变对象或更改状态

但是,在更新弱映射中的值时,我们是否会像处理变量一样改变状态?使用需要可重写的私有(private)属性时,“最佳实践”是什么?

非常感谢任何澄清!

最佳答案

回答您关于 WeakMaps 的问题,我认为你在谈论副作用。使用 Wea​​kMap 时,您可以想象设置值不会对用户产生副作用,因为 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)。

参见also , and .

关于javascript - 在weakmaps中设置新值时我们会改变状态吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60340487/

相关文章:

c++ - 声明一个对象数组 : instantiates them

javascript - 如何摆脱许多IF并使系统具有不同的元素?

oop - DDD - 持久性模型和领域模型

c# - 在 JavaScript 中使异步事件同步

c++ - 按成员复制、按位复制、浅复制和深复制有什么区别?

javascript - 如何在javascript中从对象中的对象调用方法?

javascript - 如何进入数组中的对象

Javascript 显示所有包含匹配字符串的对象

javascript - 使用 Firefox 扩展的属性触发自定义事件

javascript - 如何在单击按钮时获取div的坐标