由单线程环境中可变数据类型引起的典型问题类别是什么?

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

JS通过事件循环建模并发。结果,没有比赛条件。那么,在程序的主要范围内,以下类型的安全操作的缺点是什么,请注意以下几点:

const m = new Map([["foo", true]]);

//...

m.set("bar", false);

即使我要清空m,也不会引起任何问题,因为依赖于m的每个操作都应考虑为空情况。

也许有人可以说明可变数据类型所伴随的典型问题。

我知道这个问题可能太以意见为依据,因此,如果您认为不适合,请随时将其关闭。

提前感谢!

javascript functional-programming immutability mutable
2个回答
0
投票

[[...]因为依赖于m的每个操作都应该考虑为空情况

命名困难。假设事物可以是危险的。

我认为自己是一个务实的开发人员,有时只是发生突变。但是,您的工作是知道可能出什么问题,并对周围的人进行危险教育,以便他们做出明智的决定。

我曾经在代码审查期间指出此函数正在更改其参数:(大致看起来像这样)

function foo(bar) {
  const baz = {...bar};
  baz.a.b.c = 10;
  return baz;
}

该函数的作者回复说“不,我之前已经克隆了它。所以该函数是'pure'”。

如果我没有花时间和那个人坐下来,我们可能会遇到一个重大的生产问题。原来,他们正在改变应用程序状态,结果我们进行了一些误报测试。

对我来说,这是变异数据时可能发生的最糟糕的情况:混乱。

由突变引起的错误可能很难追溯。

[我总是鼓励团队中的人们不要为“不可能的情况”编写代码,因为这经常导致代码混乱不堪,以至于“以防万一”检查会增加维护工作量,并破坏我们对代码的信心。

但是,如果您允许uncontrol访问数据,那么“不可能的情况”就在拐角处等待。

我已经证明了人们确实在变异事物时没有意识到。当您的团队中有不同经验的人时,您可以做的最好的事情是:

  1. 从不承担任何责任
  2. 教他们
  3. 使用库强制执行不变性

也许不是您可能期望的“学术”答案,但我想我可以分享一些技巧。


0
投票

我认为没有特定的缺点,只是有些模糊的忧虑。我们可以通过遵循以下经验法则来消除疑问:

应该更改...

  1. 通过将其包装在函数作用域中,以尽可能地局部执行
  2. 从不更改给定值的类型
  3. 通过将值作为参数传递来使之明确

当然,并非总是可以避免的。但是,我认为有两种技术可以缓解该问题。以下几段是这些技术的粗略概述。

将合成值拆分为相同形状的单位

如果不预先拥有所有属性/字段,则可以将复合值拆分为形状相同的单位。所以代替

const foo = [{name: "Bob"}, {name: "Ana"}];

// ...lots of code

foo.forEach(o => {
  o.age = ...;
});

// ...lots of code

foo.forEach(o => {
  if (hasNick(o.name)) o.nick = Some(...);
  else o.nick = None;
});

我们可以写:

const foo = ["Bob", "Ana"];

// ...lots of code

const bar = [30, 28];

// ...lots of code

const baz = [None, Some("Apo")];

使用带标签的联合以允许不同的形状

如果使用标记的并集(又名和类型),则可以完全避免冗余的None / null值:

const foo = [Profile({name: "Bob", age: NaN), Profile({name: "Ana", age: NaN)];

// ...lots of code

foo.forEach(o => {
  o.age = ...;
});

// ...lots of code

// for the sake of simplicity a perform an implicit mutation with forEach
foo.forEach((o, i, xs) => {
  if (hasNick(o.name))
    xs[i] = ProfileWithNick({name: o.name, age: o.age, nick: ...});
});

因为两个构造函数ProfileProfileWithNick都创建了相同类型点2的值。

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