突变何时会成为副作用?

Bli*_*n67 2 javascript functional-programming

我遇到了以下有关如何终止未标记为功能的reduce的文章,但包含了很多有关数组突变为功能的问题。

主要答复突变数组提前打破迭代出来,但阵列可以很容易地推回拼接项目,有点暧昧的解决方案,可以说是不是在所有的功能可以恢复到原来的状态。

但是,如果可以对项目进行修改(变异),则许多算法都将获得显着优势。

对于Javascript(单线程(无工作程序),无代理),如果修改只是暂时存在,是否将其视为变异?或者函数返回后,突变是否只是副作用。

以下功能是增效剂吗?

function mutateAndRepair(arr) {  // arr is an array of numbers
    arr[0]++;
    arr[0]--;
}
Run Code Online (Sandbox Code Playgroud)
  • 该数组包含1个或多个项目。
  • 数组的第一项(索引0)是最大安全整数范围内的数字。
  • 该数组不是共享缓冲区
  • 代理未监视该阵列

我认为这不是变异,因为变异仅在函数执行时存在,并且由于JS阻止,因此没有其他代码能够看到变异,因此没有副作用。

考虑到约束条件是否符合JavaScript编码人员使用的通用功能范例?

p.s*_*w.g 5

++--运营商正在变异,他们不正是扭转对方。引用2017年标准

12.4.4.1运行时语义:评估
UpdateExpression LeftHandSideExpression ++

  1. 我们lhs要评估的结果LeftHandSideExpression
  2. 我们oldValue? ToNumber(? GetValue(lhs))
  3. newValue是增加的值的结果1,以oldValue使用相同的规则作为用于+运算符(见12.8.5)。
  4. 执行? PutValue(lhs, newValue)
  5. 返回oldValue

第二步很重要,因为它将值转换为number基元,但NumberNumber构造函数返回的对象之间也存在细微的差异。

var arr = [new Number(1234)];

function mutateAndRepair(arr) {
  console.log(`the value before is ${arr[0]}`);
  arr[0]++;
  arr[0]--;
  console.log(`the value after is ${arr[0]}`);
}

arr[0].foo = 'bar';
console.log(`foo before is ${arr[0].foo}`);
mutateAndRepair(arr)
console.log(`foo after is ${arr[0].foo}`);
Run Code Online (Sandbox Code Playgroud)

现在,通过松散解释您对第一个项目arr是“数字”的要求,我有点不客气。并且可以肯定的是,您可以添加另一条规定,即的值arr必须为“数字基元”以排除这种确切的突变形式。

还有另一个更微妙的地方。-0并且0几乎在所有方面都被视为相同的值,除了Object.is

var arr = [-0];

function mutateAndRepair(arr) {
  console.log(`the value before is ${arr[0]}`);
  arr[0]++;
  arr[0]--;
  console.log(`the value after is ${arr[0]}`);
}

console.log(`is zero before ${Object.is(0, arr[0])}`);
mutateAndRepair(arr)
console.log(`is zero after ${Object.is(0, arr[0])}`);
Run Code Online (Sandbox Code Playgroud)

好的,您可以添加第一个项目arr不是的要求-0。但是所有这些都错了。您可能会争辩说,如果您只是声明将忽略将观察到突变的任何情况,那么几乎任何方法都不会变异。

考虑到约束条件是否符合JavaScript编码人员使用的通用功能范例?

不会认为此代码遵循功能性编码原则,并且如果这是项目的目标,甚至可能会在代码审查中拒绝它。在所有代码路径中,如何或是否可以确保不变性的本质还不是那么多,但事实上,它取决于内部的突变,导致我认为该代码无法正常工作。我已经看到伪功能代码中出现了许多错误,这些错误在mutaterepair步骤之间发生异常,这当然会导致明显和意外的副作用,即使您有catch/ finally块来尝试恢复状态,那里也可能发生异常。这也许只是我的观点,但我认为不变性是更大功能的一部分样式,而不仅仅是给定功能的技术特征。