在简单的增量器中避免状态 [英] Avoiding state in simple incrementer

查看:63
本文介绍了在简单的增量器中避免状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用JavaScript函数编程技术来避免状态.我对许多基本的fp技术(例如闭包,currying等)有扎实的了解.但是我不能全神贯注于处理状态.

I'm trying to wrap my head around avoiding state using JavaScript functional programming techniques. I have a solid grasp of many basic fp techniques such as closures, currying, and so on. But I can't wrap my head around dealing with state.

我想知道创建功能性程序的人将如何实现以下非常简单的应用程序:

I'd like to know how someone creating a functional program would implement the following very simple application:

用户单击浏览器中的按钮(使用jQuery实现就可以了).每次用户单击按钮时,屏幕上的值应增加1.

A user clicks a button in the browser (jQuery implementation is fine). The value onscreen should increment by 1 each time the user clicks the button.

如何在不改变状态的情况下做到这一点?如果需要改变状态,从功能的角度来看最好的方法是什么?

How can we do this without mutating state? If mutating state is necessary, what would be the best approach from a functional perspective?

推荐答案

在这里,您将实现一个简单的计数器应用程序而无需更改DOM以外的任何内容.

Here is how you would implement a simple counter app without mutating anything except for the DOM.

const h1 = document.querySelector("h1");

const [decrement, reset, increment] = document.querySelectorAll("button");

const render = count => {
    h1.innerHTML = count; // output
    decrement.onclick = event => render(count - 1); // -+
    reset.onclick     = event => render(0);         //  |-- transition functions
    increment.onclick = event => render(count + 1); // -+
};

render(0);
//     ^
//     |
//     +-- initial state

<h1></h1>
<button>-</button>
<button>Reset</button>
<button>+</button>

这是摩尔机的示例. Moore机器是有限状态机.它由三件事组成.

This is an example of a Moore machine. A Moore machine is a finite-state machine. It consists of three things.

  1. 机器的初始状态.在我们的例子中,初始状态为0.
  2. 提供当前状态和一些输入的转换函数会产生一个新状态.
  3. 给出当前状态的输出函数产生一些输出.

在我们的例子中,我们将转换函数和输出函数组合为单个render函数.这是可能的,因为转换函数和输出函数都需要当前状态.

In our case, we combined the transition function and the output function into a single render function. This is possible because both the transition function and the output function require the current state.

向render函数提供当前状态时,它会生成一些输出,以及一个transition函数,当提供一些输入时,transition函数会生成一个新状态并更新状态机.

When the render function is provided the current state, it produces some output as well as a transition function which when provided some input, produces a new state and updates the state machine.

在本例中,我们将转换函数分为多个共享当前状态的转换函数.

In our case, we divided our transition function into multiple transition functions which share the current state.

我们还可以使用事件委托来提高性能.在下面的示例中,我们仅在整个文档上注册一个单击事件侦听器.当用户单击文档中的任意位置时,我们将检查目标元素是否具有onClick方法.如果是这样,我们会将其应用于事件.

We can also use event delegation to improve performance. In the example below we only register one click event listener on the entire document. When the user clicks anywhere in the document, we check whether the target element has an onClick method. If it does, we apply it to the event.

接下来,在render函数中,而不是为每个按钮注册单独的onclick侦听器,我们将它们存储为名为onClick的常规方法(不同情况).因为我们没有注册多个事件侦听器,这会提高应用程序的运行速度,所以它的性能更高.

Next, in the render function instead of registering separate onclick listeners for each button, we store them as regular methods named onClick (different case). This is more performant because we're not registering multiple event listeners, which would slow down the app.

const h1 = document.querySelector("h1");

const [decrement, reset, increment] = document.querySelectorAll("button");

const render = count => {
    h1.innerHTML = count;
    decrement.onClick = event => render(count - 1);
    reset.onClick     = event => render(0);
    increment.onClick = event => render(count + 1);
};

render(0);

document.addEventListener("click", event => {
    if (typeof event.target.onClick === "function") {
        event.target.onClick(event);
    }
});

<h1></h1>
<button>-</button>
<button>Reset</button>
<button>+</button>

这篇关于在简单的增量器中避免状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆