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)
我认为这不是变异,因为变异仅在函数执行时存在,并且由于JS阻止,因此没有其他代码能够看到变异,因此没有副作用。
考虑到约束条件是否符合JavaScript编码人员使用的通用功能范例?
在++和--运营商正在变异,他们不正是扭转对方。引用2017年标准:
12.4.4.1运行时语义:评估
UpdateExpression : LeftHandSideExpression ++
- 我们
lhs要评估的结果LeftHandSideExpression。- 我们
oldValue是? ToNumber(? GetValue(lhs))。- 让
newValue是增加的值的结果1,以oldValue使用相同的规则作为用于+运算符(见12.8.5)。- 执行
? PutValue(lhs, newValue)。- 返回
oldValue。
第二步很重要,因为它将值转换为number基元,但Number与Number构造函数返回的对象之间也存在细微的差异。
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编码人员使用的通用功能范例?
我不会认为此代码遵循功能性编码原则,并且如果这是项目的目标,甚至可能会在代码审查中拒绝它。在所有代码路径中,如何或是否可以确保不变性的本质还不是那么多,但事实上,它取决于内部的突变,导致我认为该代码无法正常工作。我已经看到伪功能代码中出现了许多错误,这些错误在mutate和repair步骤之间发生异常,这当然会导致明显和意外的副作用,即使您有catch/ finally块来尝试恢复状态,那里也可能发生异常。这也许只是我的观点,但我认为不变性是更大功能的一部分样式,而不仅仅是给定功能的技术特征。