具有对象的Javascript纯函数示例 [英] Javascript pure function example with objects
问题描述
我有一个不纯功能的例子。注意变量 a
超出了函数作用域的范围。为了解决这个问题,我们可以在函数内克隆对象并返回一个副本,但这是正确的方式吗?
有什么方法可以使函数 transformObject
纯?
var a = {
a:1,
b:2
};
函数transformObject(obj){
var ref = obj;
_.each(ref,function(val,index){
ref [index] = val * 2;
});
return ref;
$ bs bs = JSON.stringify
$('#code')。text(s(transformObject(a)))
$('#code2') .text(s(a))
一个纯函数遵循三个主要原则:
该函数有一个单一的职责
函数应该做只有一件事。
该函数没有副作用
该函数不改变其范围之外的状态。
该函数是引用透明的
该函数为相同的输入输出相同的值。
下一步是探讨这些原理在函数设计中的影响。
您的函数已经符合第一个原则,虽然名称应该改进;)
它也符合第二个原则,因为它不会修改其范围外的其他任何内容(它的输入参数)。
不幸的是,它不符合第三个原则:
var a = {
a:1,
b:2
};
var b = transformObject(a); // b = {2,4}
var c = transformObject(a); // c = {4,8}
相同的输入( a
),但输出不同。这违反了第三条原则。
透明的函数需要不可变的数据。
Nina Scholz 已经发布了一个很好的答案:
函数transformObject(a){
var b = {}; (b){b [k] = a [k] * 2;});
return b;
}
但它只能用,因为输入对象不包含任何嵌套的其他对象它现在有一些很好的库,可以为你提供不可变的结构(比如 一个使用ImmutableJS的简单示例: 您可以阅读更多关于不可变API的信息这里 I have the example below of an impure function. Note the variable What are some options to make the function https://jsfiddle.net/br17kk2h/1/ A pure function follows three main principles: The function should do only one thing. The function does not change state outside its scope. The function outputs the same value for the same inputs. The next step is to explore the impact of these principles in the design of the function. Your function already meets the first principle, although the name should be improved ;) And it meets the second principle too, because it doesn't modify anything else outside its scope (its input parameters). Unfortunately it doesn't meet the third principle: Same inputs ( Referentially transparent functions needs immutable data. A good answer has already been posted by Nina Scholz: But it only works because the input object does not contain any other object nested in it. Right now there are some good libraries that gives you immutable structures (like ImmutableJS). A simple example using ImmutableJS: You can read more about immutable API here 这篇关于具有对象的Javascript纯函数示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
<$ ($)$ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $ $' ;'
}
it('is immutable',()=> {
let state = List.of('Avengers','Antman') ;
let nextState = addMovie(state,'超人');
expect(nextState).to.equal(List.of(
'Avengers',
''Antman',
'超人'
));
expect(state).to.equal(List.of(
'Avengers',
'Antman'
));
});
('可以更新并返回另一个不可变列表',()=> {
let state = List.of(1,2,3,4) ;
let nextState = state.map(value => value * 2);
expect(nextState).to.equal(List.of(2,4, 6,8));
expect(state).to.equal(List.of(1,2,3,4));
});
});
a
is outside of the function scope is being changed. To get around it, one could clone the object inside the function and return a copy, but is that the right way?transformObject
pure?var a = {
a : 1,
b : 2
};
function transformObject(obj) {
var ref = obj;
_.each(ref, function(val, index){
ref[index] = val*2;
});
return ref;
}
s=JSON.stringify
$('#code').text(s(transformObject(a)))
$('#code2').text(s(a))
The function has a single responsibility
The function has no side effects
The function is referentially transparent
var a = {
a : 1,
b : 2
};
var b = transformObject(a);//b = {2, 4}
var c = transformObject(a);//c = {4, 8}
a
) but different outputs. That violates the third principle.function transformObject(a) {
var b = {};
Object.keys(a).forEach(function (k) { b[k] = a[k] * 2; });
return b;
}
describe('a List', () => {
function addMovie(currentState, movie) {
return currentState.push(movie);
}
it('is immutable', () => {
let state = List.of('Avengers', 'Antman');
let nextState = addMovie(state, 'Superman');
expect(nextState).to.equal(List.of(
'Avengers',
'Antman',
'Superman'
));
expect(state).to.equal(List.of(
'Avengers',
'Antman'
));
});
it('can be updated and returns another immutable List', () => {
let state = List.of(1,2,3,4);
let nextState = state.map(value => value*2);
expect(nextState).to.equal(List.of(2,4,6,8));
expect(state).to.equal(List.of(1,2,3,4));
});
});