用一顿简餐来解释JavaScript中的状态

by Kevin Kononenko

凯文·科诺年科(Kevin Kononenko)

用一顿简餐来解释JavaScript中的状态 (State in JavaScript explained by cooking a simple meal)

If you have ever cooked a meal at home, then you can understand how to write stateful code using object-oriented programming methods in JavaScript.

如果您曾经在家中做过饭,那么您可以了解如何使用JavaScript中的面向对象编程方法编写有状态的代码。

When you start writing simple JavaScript programs, you don’t need to worry about the number of variables you are using, or how different functions and objects work together.

当您开始编写简单JavaScript程序时,您无需担心所使用的变量数量,也不必担心不同的函数和对象如何协同工作。

For example, most people start out by using a lot of global variables, or variables that are scoped at the top level of the file. They are not part of any individual class, object or function.

例如,大多数人开始使用大量的全局变量或作用域位于文件顶层的变量。 它们不是任何单独的类,对象或函数的一部分。

For example, this is a global variable called state:

例如,这是一个名为state的全局变量:

let state = "global";

But once your program starts to involve many different functions and/or objects, you will need to create a more rigorous set of rules for your code.

但是一旦程序开始涉及许多不同的功能和/或对象,您将需要为代码创建一套更严格的规则。

This is where the concept of state comes into play. State describes the status of the entire program or an individual object. It could be text, a number, a boolean, or another data type.

这就是国家概念发挥作用的地方。 状态描述整个程序或单个对象的状态。 它可以是文本,数字,布尔值或其他数据类型。

It’s a common tool for coordinating code. For example, once you update state, a bunch of different functions can instantly react to that change.

这是用于协调代码的常用工具。 例如,更新状态后,许多不同的功能可以立即对更改做出React。

This article describes state in the context of React, a popular JavaScript library.

本文介绍了流行JavaScript库React上下文中的状态

But guess what? Even state can give you headaches once your code gets complicated! Changing state can cause unintended consequences.

但猜猜怎么了? 一旦您的代码变得复杂,甚至状态也会让您头疼! 更改状态可能会导致意想不到的后果。

Let’s stop right there. State is a popular tool in object-oriented programming, or OOP. But many programmers prefer functional programming, which discourages state changes. JavaScript supports both paradigms.

让我们停在那儿。 状态是面向对象编程或OOP中流行的工具。 但是许多程序员更喜欢函数式编程,这会阻止状态更改。 JavaScript支持两种范例。

Okay, that’s a lot of terminology at once. I wanted to find a way to show how OOP and functional programming can accomplish the same goals, even if functional programming does not use state.

好的,一次有很多术语。 我想找到一种方法来显示OOP和函数式编程如何实现相同的目标,即使函数式编程不使用状态。

This tutorial will show how you might cook a meal of spaghetti and sauce from an OOP and a functional perspective.

本教程将从OOP和功能角度说明如何烹饪意大利面条和酱汁。

Here’s a quick preview of the two different approaches:

这是两种不同方法的快速预览:

Let’s jump into it. In order to understand this tutorial, you just need to understand functions and objects in JavaScript.

让我们跳进去。 为了理解本教程,您只需要了解JavaScript中的函数和对象。

面向对象的方法(使用状态) (Object-Oriented Method (Using State))

In the graphic above, we showed two different approaches to making this pasta dinner:

在上图中,我们展示了两种制作意大利面晚餐的方法:

  1. A method that is focused on the state of the different tools, like the stove, the pot and the pasta.

    一种着眼于不同工具(例如火炉,锅和面食)状态的方法。
  2. A method that is focused on the progression of the food itself, with no mention of state of the individual tools (pots, stoves etc.)

    一种专注于食物本身发展的方法,没有提到各个工具(锅,炉子等)的状态

The object-oriented approach focuses on updating state, so our code will have state at two different levels:

面向对象的方法着重于更新状态,因此我们的代码将具有两个不同级别的状态:

  1. Global, or the state of this entire meal.

    全球,或整顿饭的状态。
  2. Local for each object.

    每个对象的本地对象。

We are going to use ES6 syntax in this tutorial to create objects. Here’s an example of global state and the “Pot” prototype.

在本教程中,我们将使用ES6语法创建对象。 这是全局状态和“ Pot”原型的示例。

let stoveTemp = 500;
function Pot(){  this.boilStatus = '';  this.startBoiling = function(){    if( stoveTemp > 400)      this.boilStatus = "boiling";  }}
let pastaPot = new Pot();pastaPot.startBoiling();
console.log(pastaPot);// Pot { boilStatus = 'boiling'; }

Note: I simplified the console.log statement to focus on the state update.

注意:我简化了console.log语句,使其专注于状态更新。

Here’s a visual representation of that logic:

这是该逻辑的直观表示:

Before

之前

After

There are two states, and when the pastaPot is created via the Pot prototype, it initially has an empty boilStatus. But then, there is a state change.

有两种状态,当通过Pot原型创建pastaPot时,它最初具有一个空的boilStatus 。 但随后,状态发生了变化。

We run pastaPot.startBoiling(), and now the boilStatus (local state) is “boiling”, since the global state of stoveTemp is over 400.

我们运行pastaPot.startBoiling() ,现在boilStatus (本地状态)为“沸腾”,因为stoveTemp的全局状态超过400。

Now let’s go one step further. We will allow the pasta to become boiled due to the state of pastaPot.

现在,让我们更进一步。 由于pastaPot的状态,我们将使意大利面煮沸。

Here’s the code we will add to the snippet above:

这是我们将添加到以上代码段中的代码:

function Pasta (){  this.cookedStatus = false;  this.addToPot = function (boilStatus){    if(boilStatus == "boiling")      this.cookedStatus = true;  }}
let myMeal = new Pasta();myMeal.addToPot(pastaPot.boilStatus);
console.log(myMeal.cookedStatus);// true

Woah! That’s a lot at once. Here’s what happened.

哇! 一次很多。 这是发生了什么事。

  1. We created a new prototype of “Pasta”, where every object will have a local state called cookedStatus

    我们创建了一个新的“ Pasta”原型,其中每个对象都将具有一个称为cookedStatus的局部状态。

  2. We created a new instance of Pasta called myMeal

    我们创建了一个名为myMeal的Pasta新实例

  3. We used the state from the pastaPot object that we created in the last snippet to determine if we should update the state called cookedStatus in myMeal to cooked.

    我们使用的状态下,从pastaPot对象,我们在过去的片断创建,以确定是否应该更新呼吁,国家cookedStatusmyMeal熟。

  4. Since the state of boilStatus in pastaPot was “boiling”, our pasta is now cooked!

    由于boilStatus中的pastaPot状态处于“沸腾”状态,因此我们的意大利面现已烹制!

Here’s that process visually:

这是直观的过程:

Before

之前

After

So, we now have the local state of one object, that depends on the local state of another object. And that local state depended on some global state! You can see how this can be challenging. But, it is at least easy to follow for now, since states are updated explicitly.

因此,我们现在有了一个对象的局部状态,这取决于另一个对象的局部状态。 那个地方国家取决于某个全球国家! 您会看到这是多么具有挑战性。 但是,由于状态已显式更新,因此至少现在很容易理解。

功能方法(无状态) (Functional Method (without state))

In order to fully understand state, you should be able to find a way to accomplish the same outcome as the code above without actually modifying state. This is where functional programming helps!

为了完全理解状态,您应该能够找到一种方法来完成与上述代码相同的结果,而无需实际修改状态。 这就是函数式编程的帮助!

Functional programming has two core values that separate it from OOP: immutability and pure functions.

函数式编程具有两个与OOP分开的核心价值:不变性和纯函数。

I am not going to go into too much depth on those topics, but if you want to learn more, I encourage you to check out this guide to functional programming in JavaScript.

我不会在这些主题上进行过多的探讨,但是如果您想了解更多,我鼓励您阅读本 JavaScript 函数编程指南

Both of these principles discourage the use of state modification in your code. That means that we can’t use local or global state.

这两个原则都不鼓励在代码中使用状态修改。 这意味着我们不能使用局部或全局状态。

Functional programming instead encourages us to pass in parameters to individual functions. We can use outside variables, but we can’t use them as state.

相反,函数式编程鼓励我们将参数传递给各个函数。 我们可以使用外部变量,但不能将它们用作状态。

Here’s an example of a function that will boil the pasta:

这是将意大利面煮沸的函数的示例:

const stoveTemp = 500;
const cookPasta = (temp) => {  if(temp > 400)    return 'cooked';}
console.log(cookPasta(stoveTemp));// 'cooked'

This code will successfully return a string of ‘cooked’. But notice — there is no object that we are updating. The function simply returns the value that will be used in the next step.

此代码将成功返回字符串“ cooked”。 但是请注意-我们没有要更新的对象。 该函数仅返回将在下一步中使用的值。

Instead, we are focused on the inputs and outputs of one function: cookPasta.

相反,我们专注于一个功能的输入和输出: cookPasta

This perspective looks at the transformation of the food itself, rather than the tools that are used to cook it. It’s a little harder to visualize, but we don’t need to have the function depend on external state.

这种观点着眼于食物本身的变化,而不是用于烹饪的工具。 可视化起来有点困难,但是我们不需要功能依赖于外部状态。

Here’s what it looks like:

看起来是这样的:

Think of it as a “timeline view” for the progress of the meal — this particular function just covers the first part, the transition from dry pasta to cooked pasta.

可以将其视为进餐过程的“时间轴视图”-此特定功能仅涵盖第一部分,即从干面食到熟面食的过渡。

Now let’s cover the second part as the food is served. Here’s the code that will serve the meal. It will come after the code block above:

现在让我们讨论食物的第二部分。 这是将用于用餐的代码。 它将在上面的代码块之后:

const serveMeal = (pasta) => { if (pasta == 'cooked')   return 'Dinner is ready.'}
console.log( serveMeal(cookPasta(stoveTemp)) );// 'Dinner is ready.'

Now, we are delivering the results of the cookPasta function directly into the serveMeal function. Again, we are able to do this without changing state, or changing data structures.

现在,我们将cookPasta函数的结果直接传递到serveMeal函数中。 同样,我们能够做到这一点而无需更改状态或更改数据结构。

Here’s a diagram that uses the “timeline view” to show how these two functions work together:

这是一个使用“时间轴视图”的图,显示了这两个功能如何协同工作:

对更多视觉教程感兴趣? (Interested In More Visual Tutorials?)

If you enjoyed this guide, give it a “clap”!

如果您喜欢本指南,请给它一个“掌声”!

And, if you would like to read more visual tutorials about HTML, CSS and JavaScript, check out the main CodeAnalogies site for 50+ tutorials.

而且,如果您想阅读有关HTML,CSS和JavaScript的更多直观教程,请访问主要的CodeAnalogies网站以获得50多个教程。

翻译自: https://www.freecodecamp.org/news/state-in-javascript-explained-by-cooking-a-simple-meal-2baf10a787ee/

在SQL,可以使用不同的语法来限制返回数据的条数。具体的语法取决于所使用的数据库管理系统。 在Oracle,可以使用ROWNUM关键字来限制返回的数据条数。以下是一个示例查询语句: SELECT * FROM tbl_name WHERE ROWNUM <= 100; 在MySQL,可以使用LIMIT关键字来限制返回的数据条数。以下是一个示例查询语句: SELECT * FROM tbl_name LIMIT 100; 在Sybase,可以使用"set rowcount X"语句来限制查询的数据条数。以下是一个示例查询语句: SET ROWCOUNT 100; SELECT * FROM tbl_name; 对于其他数据库管理系统,可能有类似的语法来实现限制返回数据条数的功能。请根据所使用的数据库管理系统的文档进行查询。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [关于各个数据库限制取出数据条数的简餐操作](https://download.csdn.net/download/weixin_38590996/13688703)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [ORACLE和SYBASE数据库实现数据查询条数限制的SQL语句实现](https://blog.csdn.net/weixin_34884417/article/details/116348763)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值