我目前正在考虑在我的代码中使用大多数纯函数。我意识到了这一点的好处。但是,我想知道更新状态变量,调用模块中定义的方法以及如何处理窗口函数时的最佳实践。
使用下面的示例,我们假设我有一个模块MyModule
。
MyModule.calculate
功能是纯粹的,所以不用担心。MyModule.trackSomething
函数正在更新MyModule.count
以跟踪它,以便在MyModule.assignEventHandlers
函数中使用的事件处理程序中使用。这不纯粹,因为它使用外部引用变量。即使我重构计算一个对象并将其作为参数传递给MyModule.trackSomething
,我仍然会通过引用改变该值,使其不纯。MyModule.assignEventHandlers
函数中,我使用全局窗口对象函数。这使得它不纯,因为我引用了外部函数。在调用函数时,是否应该通过引用传递窗口对象?MyModule.init
功能中,我正在调用MyModule.assignEventHandlers
功能。我想这也是不纯的,因为MyModule.assignEventHandlers
是一个外部参考。所以我的问题是:处理最后3个要点的最佳方法是什么?
非常感谢任何建议。谢谢!
const MyModule = {
calculate(a, b) {
return a + b;
},
count: 0,
trackSomething() {
MyModule.count += 1;
},
assignEventHandlers() {
// assign event handlers to some DOM elements
window.document.getElementById('my-ele').addEventListener('click', () => {
window.alert(MyModule.count);
MyModule.trackSomething(MyModule.count);
});
},
init() {
MyModule.assignEventHandlers();
}
};
答案 0 :(得分:0)
我认为当我们提出一个解决方案时,不仅仅关注纯粹和不纯的功能,最好还是专注于实用性。可以使用不纯的功能。
这是使用RxJs的另一个版本的实现 - 一个反应性的js lib。也使用ES6类而不是模块。请查看action
和action2
。两者都以不同的方式产生相同的结果。
在我看来,action
已经足够了。不需要让一切都超级纯净。
class MyClass {
constructor(elementId) {
this.ele = document.getElementById(elementId);
this.click$ = Rx.Observable.fromEvent(this.ele, 'click');
this.count = new Rx.BehaviorSubject(0);
}
calculate(a, b) {
return a + b;
}
action() {
window.alert(this.count.getValue());
const nextVal = this.calculate(this.count.getValue(), 1);
this.count.next(nextVal);
}
action2(log, subject, method) {
log(subject.getValue());
const nextVal = method(subject.getValue(), 1);
subject.next(nextVal);
}
}
const a = new MyClass('my-ele1');
a.click$.subscribe(() => a.action2(window.alert, a.count, a.calculate));
const b = new MyClass('my-ele2');
b.click$.subscribe(() => b.action());
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.6/Rx.min.js"></script>
<button type="button" id="my-ele1">me1</button>
<br>
<button type="button" id="my-ele2">me2</button>