[在弱映射中设置新值时,我们会更改状态吗?

问题描述 投票:0回答:1

假设我们有以下代码:

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

但是,像在变量的情况下一样,在弱映射中更新值时,我们不改变状态吗?使用需要改写的私人道具时,“最佳做法”是什么?

任何澄清都非常感谢!

javascript oop javascript-objects es6-class weakmap
1个回答
1
投票

要回答关于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和模块也可以使用。有关更多详细信息,请参见下面的链接。

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

请参见alsoand


-1
投票

我不会说更改对象的状态是一种不好的做法,在某些情况下,它是好的,而在某些情况下,它不是。

此外,在某些情况下,如果不更改对象或重新分配变量就无法解决(有些人也建议不要这样做)。

就是这种情况:否则将是不可能的。

现在,回答问题:

更新WeakMap中的值是否会更改其状态?

更改其状态,但不做对其进行突变(不更改[[properties)。

在这种情况下,这是不好的做法吗?

否!

这样做是完全正确的,并且如果有人说这是一种不好的做法,请考虑:那么还有更好的方法吗?

[存储可修改的数据,除非在某些时候修改某些数据。

© www.soinside.com 2019 - 2024. All rights reserved.