From f719d153d5257d62c6ce3e6dc05b1e140a11c565 Mon Sep 17 00:00:00 2001 From: niayyy Date: Wed, 25 Mar 2020 20:18:28 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E6=8E=8C=E6=8F=A1=20JavaScript=20=E9=9D=A2?= =?UTF-8?q?=E8=AF=95=EF=BC=9A=E4=BB=80=E4=B9=88=E6=98=AF=E7=BA=AF=E5=87=BD?= =?UTF-8?q?=E6=95=B0=EF=BC=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 掌握 JavaScript 面试:什么是纯函数? --- ...cript-interview-what-is-a-pure-function.md | 182 +++++++++--------- 1 file changed, 90 insertions(+), 92 deletions(-) diff --git a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md index cb94a7cd35f..4df3a52e0af 100644 --- a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md +++ b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md @@ -2,119 +2,118 @@ > * 原文作者:[Eric Elliott](https://medium.com/@_ericelliott) > * 译文出自:[掘金翻译计划](https://github.com/xitu/gold-miner) > * 本文永久链接:[https://github.com/xitu/gold-miner/blob/master/TODO1/master-the-javascript-interview-what-is-a-pure-function.md](https://github.com/xitu/gold-miner/blob/master/TODO1/master-the-javascript-interview-what-is-a-pure-function.md) -> * 译者: +> * 译者:[niayyy-S](https://github.com/niayyy-S) > * 校对者: -# Master the JavaScript Interview: What is a Pure Function? - +# 掌握 JavaScript 面试:什么是纯函数? ![Image: Pure — carnagenyc (CC-BY-NC 2.0)](https://cdn-images-1.medium.com/max/2048/1*gF8oCkYNvktBbAAG-nxYrg.jpeg) -Pure functions are essential for a variety of purposes, including functional programming, reliable concurrency, and React+Redux apps. But what does “pure function” mean? +纯函数对各种目的来说都是重要的,包括函数式编程,高并发和 React + Redux 构造的应用程序。但是纯函数是什么意思? -We’re going to answer this question with a free lesson from [“Learn JavaScript with Eric Elliott”](http://ericelliottjs.com/product/lifetime-access-pass/): +我们将通过来自 [通过 Eric Elliott 学习 JavaScript](http://ericelliottjs.com/product/lifetime-access-pass/) 的免费课程来回答的这个问题: -Before we can tackle what a pure function is, it’s probably a good idea to take a closer look at functions. There may be a different way to look at them that will make functional programming easier to understand. +在我们解决什么是纯函数之前,仔细研究一下函数可能更好。观察他们有什么不同,这将会使函数式编程更易于理解。 -#### What is a Function? +#### 什么是函数? -A **function** is a process which takes some input, called **arguments**, and produces some output called a **return value**. Functions may serve the following purposes: +**函数**是一个过程:它需要一些叫做**参数**输入,然后产生一些叫做**返回值**输出。函数可以用于以下目的: -* **Mapping:** Produce some output based on given inputs. A function **maps** input values to output values. -* **Procedures:** A function may be called to perform a sequence of steps. The sequence is known as a procedure, and programming in this style is known as **procedural programming**. -* **I/O:** Some functions exist to communicate with other parts of the system, such as the screen, storage, system logs, or network. +* **映射:**基于输入值产生一些的输出。函数把输入值**映射到**输出值。 +* **过程化:**可以调用一个函数去执行一系列步骤。该一系列步骤称为过程,而这种方式的编程称为**过程编程**。 +* **I / O:**一些函数存在与系统其他部分进行通信,例如屏幕,存储,系统日志或网络。 -#### Mapping +#### 映射 -Pure functions are all about mapping. Functions map input arguments to return values, meaning that for each set of inputs, there exists an output. A function will take the inputs and return the corresponding output. +纯函数都是关于映射的。函数将输入参数映射到返回值,这意味着对于每个输入,都存在对应的输出。函数将获取输入并返回相应的输出。 -**`Math.max()`** takes numbers as arguments and returns the largest number: +**`Math.max()`** 以数字作为参数并返回最大数字: ``` Math.max(2, 8, 5); // 8 ``` -In this example, 2, 8, & 5 are **arguments**. They’re values passed into the function. +在此示例中,2,8 和 5 是**参数**。它们是传递给函数的值。 -**`Math.max()`** is a function that takes any number of arguments and returns the largest argument value. In this case, the largest number we passed in was 8, and that’s the number that got returned. +**`Math.max()`** 是一个可以接受任意数量的参数并返回最大参数值的函数。在这个案例中,我们传入的最大数是 8,对应了返回的数字。 -Functions are really important in computing and math. They help us process data in useful ways. Good programmers give functions descriptive names so that when we see the code, we can see the function names and understand what the function does. +函数在计算和数学中非常重要。它们帮助我们用合适的方式处理数据。好的程序员会给函数起描述性的名称,以便当我们查看代码时,我们可以通过函数名了解函数的作用。 -Math has functions, too, and they work a lot like functions in JavaScript. You’ve probably seen functions in algebra. They look something like this: +数学也有函数,它们的工作方式与JavaScript中的函数非常相似。您可能见过代数函数。他们看起来像这样: **f**(**x**) = 2**x** -Which means that we’re declaring a function called f and it takes an argument called x and multiplies x by 2. +这意味着我们要声明了一个名为 f 的函数,它接受一个叫 x 的参数并将 x 乘以 2。 -To use this function, we simply provide a value for x: +要使用这个函数,我们只需为 x 提供一个值: **f**(2) -In algebra, this means exactly the same thing as writing: +在代数中,这意味着与编写完全相同: 4 -So any place you see **f**(2) you can substitute 4. +因此,在任何看到 **f**(2) 的地方都可以替换 4。 -Now let’s convert that function to JavaScript: +现在让我们用 JavaScript 来描述这个函数: ``` const double = x => x * 2; ``` -You can examine the function’s output using **`console.log()`**: +你可以使用 **`console.log()`** 检查函数输出: ``` console.log( double(5) ); // 10 ``` -Remember when I said that in math functions, you could replace **`f(2)`** with **`4`**? In this case, the JavaScript engine replaces **`double(5)`** with the answer, **`10`**. +还记得我说过的在数学函数中,你可以替换 **`f(2)`** 为 **`4`** 吗?在这种情况下,JavaScript引擎用 **`10`** 替换**`double(5)`**。 -So, **`console.log( double(5) );`** is the same as **`console.log(10);`** +因此,**`console.log( double(5) );`** 与**`console.log(10);`** 相同 -This is true because **`double()`** is a pure function, but if **`double()`** had side-effects, such as saving the value to disk or logging to the console, you couldn’t simply replace **`double(5)`** with 10 without changing the meaning. +这是真实存在的,因为 **`double()`** 是一个纯函数,但是如果 **`double()`** 有副作用,例如将值保存到磁盘或打印到控制台,用10 替换 **`double(5)`** 会改变函数的含义。 -If you want referential transparency, you need to use pure functions. +如果想要引用透明,则需要使用纯函数。 -#### Pure Functions +#### 纯函数 -A **pure function** is a function which: +**纯函数**是一个函数,其中: -* Given the same input, will always return the same output. -* Produces no side effects. +* 给定相同的输入,将始终返回相同的输出。 +* 无副作用。 -> A dead giveaway that a function is impure is if it makes sense to call it without using its return value. For pure functions, that’s a noop. +> 如果函数在不返回值的情况下调用是有意义的,则毫无疑问不是纯函数。对于纯函数,那是不可能的。 -I recommend that you favor pure functions. Meaning, if it is practical to implement a program requirement using pure functions, you should use them over other options. Pure functions take some input and return some output based on that input. They are the simplest reusable building blocks of code in a program. Perhaps the most important design principle in computer science is KISS (Keep It Simple, Stupid). I prefer Keep It Stupid Simple. Pure functions are stupid simple in the best possible way. +我建议你偏向于使用纯函数。意思是,如果使用纯函数实现程序需求是可行的,应该优先选择使用。纯函数接受一些输入,并根据输入返回一些输出。它们是程序中最简单的可重用代码块。也许计算机科学中最重要的设计原理是 KISS(保持简单明了)。我更喜欢保持愚蠢化的简单。纯函数是愚蠢化的简单的最佳方式。 -Pure functions have many beneficial properties, and form the foundation of **functional programming**. Pure functions are completely independent of outside state, and as such, they are immune to entire classes of bugs that have to do with shared mutable state. Their independent nature also makes them great candidates for parallel processing across many CPUs, and across entire distributed computing clusters, which makes them essential for many types of scientific and resource-intensive computing tasks. +纯函数具有许多有益的特性,并构成了**函数式编程**的基础。纯函数完全独立于外部状态,因此,它们不受与共享可变状态有关的所有错误的影响。它们的独立特性也使其成为跨多个 CPU 以及整个分布式计算集群进行并行处理的极佳候选者,这使其对许多类型的科学的和资源密集型的计算任务至关重要。 -Pure functions are also extremely independent — easy to move around, refactor, and reorganize in your code, making your programs more flexible and adaptable to future changes. +纯函数也是非常独立的 —— 在代码中可以轻松移动,重构以及重组,使程序更灵活并能够适应将来的更改。 -#### The Trouble with Shared State +#### 共享状态问题 -Several years ago I was working on an app that allowed users to search a database for musical artists and load the artist’s music playlist into a web player. This was around the time Google Instant landed, which displays instant search results as you type your search query. AJAX-powered autocomplete was suddenly all the rage. +几年前,我正在开发一个应用程序,该程序允许用户搜索音乐艺术家的数据库并将该艺术家的音乐播放列表加载到 web 播放器中。大约是 Google 即搜即得上线的那个时候,当输入搜索查询时,它会显示即时搜索结果。AJAX 驱动的自动完成功能风靡一时。 -The only problem was that users often type faster than an API autocomplete search response can be returned, which caused some strange bugs. It would trigger race conditions, where newer suggestions would be replaced by outdated suggestions. +唯一的问题是,用户输入的速度通常快于 API 的自动完成搜索并返回响应的速度,从而导致一些奇怪的错误。这将触发竞争条件(rice condition),在此情况下,较新的结果可能会被过期的所取代。 -Why did that happen? Because each AJAX success handler was given access to directly update the suggestion list that was displayed to users. The slowest AJAX request would always win the user’s attention by blindly replacing results, even when those replaced results may have been newer. +为什么会这样呢?因为每个 AJAX 成功处理程序都有权直接更新显示给用户的建议列表。最慢的 AJAX 请求通过盲目替换将始终获得用户的注意,即使这些替换的结果可能是较新的。 -To fix the problem, I created a suggestion manager — a single source of truth to manage the state of the query suggestions. It was aware of a currently pending AJAX request, and when the user typed something new, the pending AJAX request would be canceled before a new request was issued, so only a single response handler at a time would ever be able to trigger a UI state update. +为了解决这个问题,我创建了一个建议管理器 —— 一个单一数据源去管理查询建议的状态。它知道当前有一个待处理的 AJAX 请求,并且当用户输入新内容时,这个待处理的 AJAX 请求将在发出新请求之前被取消,因此一次仅一个响应处理程序将能够触发 UI 状态更新。 -Any sort of asynchronous operation or concurrency could cause similar race conditions. Race conditions happen if output is dependent on the sequence of uncontrollable events (such as network, device latency, user input, randomness, etc…). In fact, if you’re using shared state and that state is reliant on sequences which vary depending on indeterministic factors, for all intents and purposes, the output is impossible to predict, and that means it’s impossible to properly test or fully understand. As Martin Odersky (creator of Scala) puts it: +任何种类的异步操作或并发都可能导致类似的竞争条件。如果输出取决于不可控事件的顺序(例如网络,设备延迟,用户输入,随机性等),则会发生竞争条件。实际上,如果你使用共享状态,并且该状态依赖于可能因不确定性因素而变化的序列,出于所有的情况和目的,输出都是无法预测的,这意味着无法正确测试或完全理解。正如 Martin Odersky(Scala 语言的创建者)所说: -> **non-determinism = parallel processing + mutable state** +> 不确定性 = 并行处理 + 可变状态 -Program determinism is usually a desirable property in computing. Maybe you think you’re OK because JS runs in a single thread, and as such, is immune to parallel processing concerns, but as the AJAX example demonstrates, a single threaded JS engine does not imply that there is no concurrency. On the contrary, there are many sources of concurrency in JavaScript. API I/O, event listeners, web workers, iframes, and timeouts can all introduce indeterminism into your program. Combine that with shared state, and you’ve got a recipe for bugs. +程序的确定性通常是计算中的理想属性。可能你认为还好,因为 JS 在单线程中运行,因此不受并行处理问题的影响,但是正如 AJAX 示例所示,单线程JS引擎并不意味着没有并发。相反,JavaScript 中有许多并发来源。API I / O,事件侦听,Web Worker,iframe 和超时都可以将不确定性引入程序中。将其与共享状态结合起来,就可以得出解决 bug 的方法。 -Pure functions can help you avoid those kinds of bugs. +纯函数可以帮助你避免这些 bug。 -#### Given the Same Input, Always Return the Same Output +#### 给定相同的输入,始终返回相同的输出 -With our **`double()`** function, you can replace the function call with the result, and the program will mean the same thing — **`double(5)`** will always mean the same thing as **`10`** in your program, regardless of context, no matter how many times you call it or when. +使用上面的 **`double()`** 函数,你可以用结果替换函数调用,程序仍然具有相同的含义 —— **`double(5)`** 始终与程序中的 **`10`** 具有相同含义,而不管上下文如何,无论调用它多少次或何时调用。 -But you can’t say the same thing about all functions. Some functions rely on information other than the arguments you pass in to produce results. +但是你不能对所有函数都这么认为。某些函数依赖于你传入的参数以外的信息来产生结果。 -Consider this example: +考虑以下示例: ``` Math.random(); // => 0.4011148700956255 @@ -122,13 +121,13 @@ Math.random(); // => 0.8533405303023756 Math.random(); // => 0.3550692005082965 ``` -Even though we didn’t pass any arguments into any of the function calls, they all produced different output, meaning that **`Math.random()`** is **not pure**. +尽管我们没有传递任何参数到任何函数调用的,他们都产生了不同的输出,这意味着 **`Math.random()`** 是**不是纯函数**。 -**`Math.random()`** produces a new random number between 0 and 1 every time you run it, so clearly you couldn’t just replace it with 0.4011148700956255 without changing the meaning of the program. +**`Math.random()`** 每次运行时,都会产生一个介于 0 和 1 之间的新随机数,因此很明显,你不能只用 0.4011148700956255 替换它而不改变程序的含义。 -That would produce the same result every time. When we ask the computer for a random number, it usually means that we want a different result than we got the last time. What’s the point of a pair of dice with the same numbers printed on every side? +那将每次都会产生相同的结果。当我们要求计算机产生一个随机数时,通常意味着我们想要一个与上次不同的结果。每一面都印着相同数字的一对骰子有什么意义呢? -Sometimes we have to ask the computer for the current time. We won’t go into the details of how the time functions work. For now, just copy this code: +有时我们必须询问计算机当前时间。我们不会详细的知道时间函数的工作原理。只需复制以下代码: ``` const time = () => new Date().toLocaleTimeString(); @@ -136,19 +135,19 @@ const time = () => new Date().toLocaleTimeString(); time(); // => "5:15:45 PM" ``` -What would happen if you replaced the **`time()`** function call with the current time? +如果用当前时间取代 **`time()`** 函数的调用会发生什么? -It would always say it’s the same time: the time that the function call got replaced. In other words, it could only produce the correct output once per day, and only if you ran the program at the exact moment that the function got replaced. +它总是输出相同的时间:这个函数调用被替换的时间。换句话说,它只能每天产生一次正确的输出,并且仅当你在替换函数的确切时刻运行程序时才可以。 -So clearly, **`time()`** isn’t like our **`double()`** function. +很明显,**`time()`** 不像 **`double()`** 函数。 -**A function is only pure if, given the same input, it will always produce the same output**. You may remember this rule from algebra class: the same input values will always map to the same output value. However, many input values may map to the same output value. For example, the following function **is pure**: +**如果函数在给定相同的输入的情况下始终产生相同的输出,则该函数是纯函数**。你可能还记得代数课上的这个规则:相同的输入值将始终映射到相同的输出值。但是,许多输入值可能会映射到相同的输出值。例如,以下函数是**纯函数**: ``` const highpass = (cutoff, value) => value >= cutoff; ``` -The same input values will always map to the same output value: +相同的输入值将始终映射到相同的输出值: ``` highpass(5, 5); // => true @@ -156,7 +155,7 @@ highpass(5, 5); // => true highpass(5, 5); // => true ``` -Many input values may map to the same output value: +许多输入值可能映射到相同的输出值: ``` highpass(5, 123); // true @@ -168,20 +167,20 @@ highpass(5, 3); // false highpass(5, 4); // false ``` -A pure function must not rely on any external mutable state, because it would no longer be deterministic or referentially transparent. +纯函数一定不能依赖任何外部可变状态,因为它不再是确定性的或引用透明的。 -## Pure Functions Produce No Side Effects +## 纯函数不会产生副作用 -A pure function produces no side effects, which means that it can’t alter any external state. +纯函数不会产生任何副作用,意味着它无法更改任何外部状态。 -## Immutability +## 不变性 -JavaScript’s object arguments are references, which means that if a function were to mutate a property on an object or array parameter, that would mutate state that is accessible outside the function. Pure functions must not mutate external state. +JavaScript的对象参数是引用的,这意味着如果函数要更改对象或数组参数上的属性,则将使该函数外部可访问的状态发生变化。纯函数不得改变外部状态。 -Consider this mutating, **impure** **`addToCart()`** function: +考虑一下这种变异的,**不纯的** **`addToCart()`** 函数: ```JavaScript -// impure addToCart mutates existing cart +// 不纯的 addToCart 函数改变了现有的 cart 对象 const addToCart = (cart, item, quantity) => { cart.items.push({ item, @@ -205,7 +204,7 @@ test('addToCart()', assert => { 1 ); - const expected = 1; // num items in cart + const expected = 1; // cart 中的商品数 const actual = cart.items.length; assert.equal(actual, expected, msg); @@ -216,15 +215,15 @@ test('addToCart()', assert => { ``` -It works by passing in a cart, and item to add to that cart, and an item quantity. The function then returns the same cart, with the item added to it. +这个函数通过传递 cart 对象,商品和数量被添加到 cart 对象上。然后,该函数返回相同的 cart 对象,并添加了商品。 -The problem with this is that we’ve just mutated some shared state. Other functions may be relying on that cart object state to be what it was before the function was called, and now that we’ve mutated that shared state, we have to worry about what impact it will have on the program logic if we change the order in which functions have been called. Refactoring the code could result in bugs popping up, which could screw up orders, and result in unhappy customers. +这样做的问题是,我们刚刚改变了一些共享状态。其他函数可能依赖于 cart 对象状态 —— 被该函数调用之前的状态,而现在我们已经更改了这个共享状态,如果我们改变函数调用的顺序,我们不得不担心将会对程序逻辑上产生怎样的影响。重构代码可能会导致 bug 出现,从而可能破坏订单并导致客户不满意。 -Now consider this version: +现在考虑这个版本: ```JavaScript -// Pure addToCart() returns a new cart -// It does not mutate the original. +// 纯 addToCart() 函数返回一个新的 cart 对象 +// 这不会改变原始对象 const addToCart = (cart, item, quantity) => { const newCart = lodash.cloneDeep(cart); @@ -243,8 +242,8 @@ test('addToCart()', assert => { items: [] }; - // deep-freeze on npm - // throws an error if original is mutated + // npm 上的 deep-freeze + // 如果原始对象被改变,则抛出一个错误 deepFreeze(originalCart); const cart = addToCart( @@ -257,7 +256,7 @@ test('addToCart()', assert => { ); - const expected = 1; // num items in cart + const expected = 1; // cart 中的商品数 const actual = cart.items.length; assert.equal(actual, expected, msg); @@ -269,36 +268,35 @@ test('addToCart()', assert => { ``` -In this example, we have an array nested in an object, which is why I reached for a deep clone. This is more complex state than you’ll typically be dealing with. For most things, you can break it down into smaller chunks. +在此示例中,我们在对象中嵌套了一个数组,这是我要进行深克隆的原因。这比你通常要处理的状态更为复杂。对于大多数事情,你可以将其分解为较小的块。 -For example, Redux lets you compose reducers rather than deal with the entire app state inside each reducer. The result is that you don’t have to create a deep clone of the entire app state every time you want to update just a small part of it. Instead, you can use non-destructive array methods, or **`Object.assign()`** to update a small part of the app state. +例如,Redux 让你可以组成 reducers,而不是在每个 reducers 中的解决整个应用程序状态。结果是,你不必每次更新整个应用程序状态的一小部分时就创建一个深克隆。相反,你可以使用非破坏性数组方法,或 **`Object.assign()`** 更新应用状态的一小部分。 -Your turn. [Fork this pen](http://codepen.io/ericelliott/pen/MyojLq?editors=0010) and change the impure functions into pure functions. Make the unit tests pass without changing the tests. +轮到你了。[Fork 这个 codepen 代码](http://codepen.io/ericelliott/pen/MyojLq?editors=0010),并将非纯函数转换为纯函数。使单元测试通过而不更改测试。 -#### Explore the Series +#### 探索这个系列 -* [What is a Closure?](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36#.ecfskj935) -* [What is the Difference Between Class and Prototypal Inheritance?](https://medium.com/javascript-scene/master-the-javascript-interview-what-s-the-difference-between-class-prototypal-inheritance-e4cd0a7562e9#.h96dymht1) -* [What is a Pure Function?](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-pure-function-d1c076bec976#.4256pjcfq) -* [What is Function Composition?](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-function-composition-20dfb109a1a0#.i84zm53fb) -* [What is Functional Programming?](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0#.jddz30xy3) -* [What is a Promise?](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261#.aa7ubggsy) -* [Soft Skills](https://medium.com/javascript-scene/master-the-javascript-interview-soft-skills-a8a5fb02c466) +* [什么是闭包?](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36#.ecfskj935) +* [类和原型继承有什么区别?](https://medium.com/javascript-scene/master-the-javascript-interview-what-s-the-difference-between-class-prototypal-inheritance-e4cd0a7562e9#.h96dymht1) +* [什么是纯函数?](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-pure-function-d1c076bec976#.4256pjcfq) +* [函数由什么构成?](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-function-composition-20dfb109a1a0#.i84zm53fb) +* [什么是函数式编程?](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0#.jddz30xy3) +* [什么是 Promise ?](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-promise-27fc71e77261#.aa7ubggsy) +* [软技能](https://medium.com/javascript-scene/master-the-javascript-interview-soft-skills-a8a5fb02c466) -> This post was included in the book “Composing Software”.**[ -Buy the Book](https://leanpub.com/composingsoftware) | [Index](https://medium.com/javascript-scene/composing-software-the-book-f31c77fc3ddc) | [\< Previous](https://medium.com/javascript-scene/why-learn-functional-programming-in-javascript-composing-software-ea13afc7a257) | [Next >](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0)** +> 该帖子已包含在《Composing Software》书中。**[ 买这本书](https://leanpub.com/composingsoftware) | [索引](https://medium.com/javascript-scene/composing-software-the-book-f31c77fc3ddc) | [<上一页](https://medium.com/javascript-scene/why-learn-functional-programming-in-javascript-composing-software-ea13afc7a257) | [下一页>](https://medium.com/javascript-scene/master-the-javascript-interview-what-is-functional-programming-7f218c68b3a0)** --- -## Learn More at EricElliottJS.com +## 在 EricElliottJS.com 上了解更多信息 -Video lessons with interactive code challenges are available for members of EricElliottJS.com. If you’re not a member, [sign up today](https://ericelliottjs.com/). +EricElliottJS.com 的成员可以观看带有交互式代码挑战的视频课程。如果你还不是会员,[立即注册](https://ericelliottjs.com/). --- -****Eric Elliott** is a distributed systems expert and author of the books, [“Composing Software”](https://leanpub.com/composingsoftware) and [“Programming JavaScript Applications”](https://ericelliottjs.com/product/programming-javascript-applications-ebook/). As co-founder of [DevAnywhere.io](https://devanywhere.io/), he teaches developers the skills they need to work remotely and embrace work/life balance. He builds and advises development teams for crypto projects, and has contributed to software experiences for **Adobe Systems,Zumba Fitness,** **The Wall Street Journal,** **ESPN,** **BBC,** and top recording artists including **Usher, Frank Ocean, Metallica,** and many more.** +**埃里克·埃利奥特(Eric Elliott)**是一名分布式系统专家,并且是[《Composing Software》](https://leanpub.com/composingsoftware)和[《Programming JavaScript Applications》](https://ericelliottjs.com/product/programming-javascript-applications-ebook/)这两本书的作者。作为 [DevAnywhere.io](https://devanywhere.io/) 的联合创始人,他教开发人员远程工作和实现工作 / 生活平衡所需的技能。他建立并为加密项目的开发团队提供咨询,并为 **Adobe 公司、Zumba Fitness、《华尔街日报》、ESPN、BBC** 和包括 **Usher、Frank Ocean、Metallica** 在内的顶级唱片艺术家的软件体验做出了贡献。 -**He enjoys a remote lifestyle with the most beautiful woman in the world.** +**他与世界上最美丽的女人一起过着远程的生活方式。** > 如果发现译文存在错误或其他需要改进的地方,欢迎到 [掘金翻译计划](https://github.com/xitu/gold-miner) 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 **本文永久链接** 即为本文在 GitHub 上的 MarkDown 链接。 From c56d79e5b899bc1b583c9f6b4da27093de0c8b9b Mon Sep 17 00:00:00 2001 From: niayyy Date: Thu, 26 Mar 2020 19:52:17 +0800 Subject: [PATCH 2/8] Update master-the-javascript-interview-what-is-a-pure-function.md --- ...cript-interview-what-is-a-pure-function.md | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md index 4df3a52e0af..add5fc6a5e6 100644 --- a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md +++ b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md @@ -8,23 +8,23 @@ # 掌握 JavaScript 面试:什么是纯函数? ![Image: Pure — carnagenyc (CC-BY-NC 2.0)](https://cdn-images-1.medium.com/max/2048/1*gF8oCkYNvktBbAAG-nxYrg.jpeg) -纯函数对各种目的来说都是重要的,包括函数式编程,高并发和 React + Redux 构造的应用程序。但是纯函数是什么意思? +纯函数对于实现各种目的是必不可少的,包括函数式编程,高并发和 React + Redux 构造的应用程序。但是纯函数是什么意思? -我们将通过来自 [通过 Eric Elliott 学习 JavaScript](http://ericelliottjs.com/product/lifetime-access-pass/) 的免费课程来回答的这个问题: +我们将通过来自 [《跟 Eric Elliott 学习 JavaScript》](http://ericelliottjs.com/product/lifetime-access-pass/) 的免费课程来回答的这个问题: -在我们解决什么是纯函数之前,仔细研究一下函数可能更好。观察他们有什么不同,这将会使函数式编程更易于理解。 +在我们解决什么是纯函数之前,仔细研究一下函数可能更好。也许存在一种不一样的看待函数的方式,会让函数式编程更易于理解。 #### 什么是函数? **函数**是一个过程:它需要一些叫做**参数**输入,然后产生一些叫做**返回值**输出。函数可以用于以下目的: * **映射:**基于输入值产生一些的输出。函数把输入值**映射到**输出值。 -* **过程化:**可以调用一个函数去执行一系列步骤。该一系列步骤称为过程,而这种方式的编程称为**过程编程**。 +* **过程化:**可以调用一个函数去执行一系列步骤。该一系列步骤称为过程,而这种方式的编程称为**面向过程编程**。 * **I / O:**一些函数存在与系统其他部分进行通信,例如屏幕,存储,系统日志或网络。 #### 映射 -纯函数都是关于映射的。函数将输入参数映射到返回值,这意味着对于每个输入,都存在对应的输出。函数将获取输入并返回相应的输出。 +纯函数都是关于映射的。函数将输入参数映射到返回值,这意味着对于每个输入的集合,都存在对应的输出。函数将获取输入并返回相应的输出。 **`Math.max()`** 以数字作为参数并返回最大数字: @@ -48,7 +48,7 @@ Math.max(2, 8, 5); // 8 **f**(2) -在代数中,这意味着与编写完全相同: +在代数中,这意味着与下面的写法完全相同: 4 @@ -81,11 +81,11 @@ console.log( double(5) ); // 10 * 给定相同的输入,将始终返回相同的输出。 * 无副作用。 -> 如果函数在不返回值的情况下调用是有意义的,则毫无疑问不是纯函数。对于纯函数,那是不可能的。 +> 如果你合理调用一个函数,而没有使用它的返回值,则毫无疑问不是纯函数。对于纯函数来说,相当于未进行调用。 -我建议你偏向于使用纯函数。意思是,如果使用纯函数实现程序需求是可行的,应该优先选择使用。纯函数接受一些输入,并根据输入返回一些输出。它们是程序中最简单的可重用代码块。也许计算机科学中最重要的设计原理是 KISS(保持简单明了)。我更喜欢保持愚蠢化的简单。纯函数是愚蠢化的简单的最佳方式。 +我建议你偏向于使用纯函数。意思是,如果使用纯函数实现程序需求是可行的,应该优先选择使用。纯函数接受一些输入,并根据输入返回一些输出。它们是程序中最简单的可重用代码块。也许计算机科学中最重要的设计原理是 KISS(保持简单明了)。我更喜欢保持傻瓜式的简单。纯函数是傻瓜式简单的最佳方式。 -纯函数具有许多有益的特性,并构成了**函数式编程**的基础。纯函数完全独立于外部状态,因此,它们不受与共享可变状态有关的所有错误的影响。它们的独立特性也使其成为跨多个 CPU 以及整个分布式计算集群进行并行处理的极佳候选者,这使其对许多类型的科学的和资源密集型的计算任务至关重要。 +纯函数具有许多有益的特性,并构成了**函数式编程**的基础。纯函数完全独立于外部状态,因此,它们不受所有与共享可变状态有关的 bug 的影响。它们的独立特性也使其成为跨多个 CPU 以及整个分布式计算集群进行并行处理的极佳候选者,这使其对许多类型的科学的和资源密集型的计算任务至关重要。 纯函数也是非常独立的 —— 在代码中可以轻松移动,重构以及重组,使程序更灵活并能够适应将来的更改。 @@ -93,13 +93,13 @@ console.log( double(5) ); // 10 几年前,我正在开发一个应用程序,该程序允许用户搜索音乐艺术家的数据库并将该艺术家的音乐播放列表加载到 web 播放器中。大约是 Google 即搜即得上线的那个时候,当输入搜索查询时,它会显示即时搜索结果。AJAX 驱动的自动完成功能风靡一时。 -唯一的问题是,用户输入的速度通常快于 API 的自动完成搜索并返回响应的速度,从而导致一些奇怪的错误。这将触发竞争条件(rice condition),在此情况下,较新的结果可能会被过期的所取代。 +唯一的问题是,用户输入的速度通常快于 API 的自动完成搜索并返回响应的速度,从而导致一些奇怪的错误。这将触发竞争条件(race condition),在此情况下,较新的结果可能会被过期的所取代。 -为什么会这样呢?因为每个 AJAX 成功处理程序都有权直接更新显示给用户的建议列表。最慢的 AJAX 请求通过盲目替换将始终获得用户的注意,即使这些替换的结果可能是较新的。 +为什么会这样呢?因为每个 AJAX 成功处理程序都有权直接更新显示给用户的建议列表。最慢的 AJAX 请求总是可以通过盲目替换获得用户的注意,即使这些替换的结果可能是较新的。 为了解决这个问题,我创建了一个建议管理器 —— 一个单一数据源去管理查询建议的状态。它知道当前有一个待处理的 AJAX 请求,并且当用户输入新内容时,这个待处理的 AJAX 请求将在发出新请求之前被取消,因此一次仅一个响应处理程序将能够触发 UI 状态更新。 -任何种类的异步操作或并发都可能导致类似的竞争条件。如果输出取决于不可控事件的顺序(例如网络,设备延迟,用户输入,随机性等),则会发生竞争条件。实际上,如果你使用共享状态,并且该状态依赖于可能因不确定性因素而变化的序列,出于所有的情况和目的,输出都是无法预测的,这意味着无法正确测试或完全理解。正如 Martin Odersky(Scala 语言的创建者)所说: +任何种类的异步操作或并发都可能导致类似的竞争条件。如果输出取决于不可控事件的顺序(例如网络,设备延迟,用户输入,随机性等),则会发生竞争条件。实际上,如果你使用共享状态,并且该状态依赖于因不确定性因素而变化的序列,总而言之,输出都是无法预测的,这意味着无法正确测试或完全理解。正如 Martin Odersky(Scala 语言的创建者)所说: > 不确定性 = 并行处理 + 可变状态 @@ -177,7 +177,7 @@ highpass(5, 4); // false JavaScript的对象参数是引用的,这意味着如果函数要更改对象或数组参数上的属性,则将使该函数外部可访问的状态发生变化。纯函数不得改变外部状态。 -考虑一下这种变异的,**不纯的** **`addToCart()`** 函数: +考虑一下这种改变的,**不纯的** **`addToCart()`** 函数: ```JavaScript // 不纯的 addToCart 函数改变了现有的 cart 对象 @@ -215,7 +215,7 @@ test('addToCart()', assert => { ``` -这个函数通过传递 cart 对象,商品和数量被添加到 cart 对象上。然后,该函数返回相同的 cart 对象,并添加了商品。 +这个函数通过传递 cart 对象,添加商品和商品数量到 cart 对象上来调用的。然后,该函数返回相同的 cart 对象,并添加了商品。 这样做的问题是,我们刚刚改变了一些共享状态。其他函数可能依赖于 cart 对象状态 —— 被该函数调用之前的状态,而现在我们已经更改了这个共享状态,如果我们改变函数调用的顺序,我们不得不担心将会对程序逻辑上产生怎样的影响。重构代码可能会导致 bug 出现,从而可能破坏订单并导致客户不满意。 @@ -296,7 +296,7 @@ EricElliottJS.com 的成员可以观看带有交互式代码挑战的视频课 **埃里克·埃利奥特(Eric Elliott)**是一名分布式系统专家,并且是[《Composing Software》](https://leanpub.com/composingsoftware)和[《Programming JavaScript Applications》](https://ericelliottjs.com/product/programming-javascript-applications-ebook/)这两本书的作者。作为 [DevAnywhere.io](https://devanywhere.io/) 的联合创始人,他教开发人员远程工作和实现工作 / 生活平衡所需的技能。他建立并为加密项目的开发团队提供咨询,并为 **Adobe 公司、Zumba Fitness、《华尔街日报》、ESPN、BBC** 和包括 **Usher、Frank Ocean、Metallica** 在内的顶级唱片艺术家的软件体验做出了贡献。 -**他与世界上最美丽的女人一起过着远程的生活方式。** +**他与世界上最美丽的女人一起享受着远程的生活方式。** > 如果发现译文存在错误或其他需要改进的地方,欢迎到 [掘金翻译计划](https://github.com/xitu/gold-miner) 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 **本文永久链接** 即为本文在 GitHub 上的 MarkDown 链接。 From 3ea5a9dc0c00794884948f8a88e69553794fc6d0 Mon Sep 17 00:00:00 2001 From: niayyy Date: Thu, 26 Mar 2020 19:57:14 +0800 Subject: [PATCH 3/8] Update master-the-javascript-interview-what-is-a-pure-function.md --- .../master-the-javascript-interview-what-is-a-pure-function.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md index add5fc6a5e6..0361783ac3c 100644 --- a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md +++ b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md @@ -3,7 +3,7 @@ > * 译文出自:[掘金翻译计划](https://github.com/xitu/gold-miner) > * 本文永久链接:[https://github.com/xitu/gold-miner/blob/master/TODO1/master-the-javascript-interview-what-is-a-pure-function.md](https://github.com/xitu/gold-miner/blob/master/TODO1/master-the-javascript-interview-what-is-a-pure-function.md) > * 译者:[niayyy-S](https://github.com/niayyy-S) -> * 校对者: +> * 校对者:[chaingangway](https://github.com/chaingangway) # 掌握 JavaScript 面试:什么是纯函数? ![Image: Pure — carnagenyc (CC-BY-NC 2.0)](https://cdn-images-1.medium.com/max/2048/1*gF8oCkYNvktBbAAG-nxYrg.jpeg) From 117e234ec9910558d619ec5079bfb91955860c52 Mon Sep 17 00:00:00 2001 From: niayyy Date: Fri, 27 Mar 2020 20:22:29 +0800 Subject: [PATCH 4/8] Update master-the-javascript-interview-what-is-a-pure-function.md --- ...cript-interview-what-is-a-pure-function.md | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md index 0361783ac3c..af56c4caa28 100644 --- a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md +++ b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md @@ -3,7 +3,7 @@ > * 译文出自:[掘金翻译计划](https://github.com/xitu/gold-miner) > * 本文永久链接:[https://github.com/xitu/gold-miner/blob/master/TODO1/master-the-javascript-interview-what-is-a-pure-function.md](https://github.com/xitu/gold-miner/blob/master/TODO1/master-the-javascript-interview-what-is-a-pure-function.md) > * 译者:[niayyy-S](https://github.com/niayyy-S) -> * 校对者:[chaingangway](https://github.com/chaingangway) +> * 校对者:[chaingangway](https://github.com/chaingangway)、[IAMSHENSH](https://github.com/IAMSHENSH) # 掌握 JavaScript 面试:什么是纯函数? ![Image: Pure — carnagenyc (CC-BY-NC 2.0)](https://cdn-images-1.medium.com/max/2048/1*gF8oCkYNvktBbAAG-nxYrg.jpeg) @@ -12,7 +12,7 @@ 我们将通过来自 [《跟 Eric Elliott 学习 JavaScript》](http://ericelliottjs.com/product/lifetime-access-pass/) 的免费课程来回答的这个问题: -在我们解决什么是纯函数之前,仔细研究一下函数可能更好。也许存在一种不一样的看待函数的方式,会让函数式编程更易于理解。 +在我们解决什么是纯函数这个问题之前,仔细研究一下什么是函数可能更好。也许存在一种不一样的看待函数的方式,会让函数式编程更易于理解。 #### 什么是函数? @@ -24,9 +24,9 @@ #### 映射 -纯函数都是关于映射的。函数将输入参数映射到返回值,这意味着对于每个输入的集合,都存在对应的输出。函数将获取输入并返回相应的输出。 +纯函数都是关于映射的。函数将输入参数映射到返回值,这意味着对于每组输入,都存在对应的输出。函数将获取输入并返回相应的输出。 -**`Math.max()`** 以数字作为参数并返回最大数字: +**`Math.max()`** 以一组数字作为参数并返回最大数字: ``` Math.max(2, 8, 5); // 8 @@ -38,7 +38,7 @@ Math.max(2, 8, 5); // 8 函数在计算和数学中非常重要。它们帮助我们用合适的方式处理数据。好的程序员会给函数起描述性的名称,以便当我们查看代码时,我们可以通过函数名了解函数的作用。 -数学也有函数,它们的工作方式与JavaScript中的函数非常相似。您可能见过代数函数。他们看起来像这样: +数学也有函数,它们的工作方式与 JavaScript 中的函数非常相似。您可能见过代数函数。他们看起来像这样: **f**(**x**) = 2**x** @@ -66,9 +66,9 @@ const double = x => x * 2; console.log( double(5) ); // 10 ``` -还记得我说过的在数学函数中,你可以替换 **`f(2)`** 为 **`4`** 吗?在这种情况下,JavaScript引擎用 **`10`** 替换**`double(5)`**。 +还记得我说过的在数学函数中,你可以替换 **`f(2)`** 为 **`4`** 吗?在这种情况下,JavaScript 引擎用 **`10`** 替换 **`double(5)`**。 -因此,**`console.log( double(5) );`** 与**`console.log(10);`** 相同 +因此, **`console.log( double(5) );`** 与 **`console.log(10);`** 相同 这是真实存在的,因为 **`double()`** 是一个纯函数,但是如果 **`double()`** 有副作用,例如将值保存到磁盘或打印到控制台,用10 替换 **`double(5)`** 会改变函数的含义。 @@ -85,23 +85,23 @@ console.log( double(5) ); // 10 我建议你偏向于使用纯函数。意思是,如果使用纯函数实现程序需求是可行的,应该优先选择使用。纯函数接受一些输入,并根据输入返回一些输出。它们是程序中最简单的可重用代码块。也许计算机科学中最重要的设计原理是 KISS(保持简单明了)。我更喜欢保持傻瓜式的简单。纯函数是傻瓜式简单的最佳方式。 -纯函数具有许多有益的特性,并构成了**函数式编程**的基础。纯函数完全独立于外部状态,因此,它们不受所有与共享可变状态有关的 bug 的影响。它们的独立特性也使其成为跨多个 CPU 以及整个分布式计算集群进行并行处理的极佳候选者,这使其对许多类型的科学的和资源密集型的计算任务至关重要。 +纯函数具有许多有益的特性,并构成了**函数式编程**的基础。纯函数完全独立于外部状态,因此,它们不受所有与共享可变状态有关问题的影响。它们的独立特性也使其成为跨多个 CPU 以及整个分布式计算集群进行并行处理的极佳选择,这使其对许多类型的科学和资源密集型计算任务至关重要。 纯函数也是非常独立的 —— 在代码中可以轻松移动,重构以及重组,使程序更灵活并能够适应将来的更改。 #### 共享状态问题 -几年前,我正在开发一个应用程序,该程序允许用户搜索音乐艺术家的数据库并将该艺术家的音乐播放列表加载到 web 播放器中。大约是 Google 即搜即得上线的那个时候,当输入搜索查询时,它会显示即时搜索结果。AJAX 驱动的自动完成功能风靡一时。 +几年前,我正在开发一个应用程序,该程序允许用户搜索音乐艺术家的数据库并将该艺术家的音乐播放列表加载到 web 播放器中。大约在 Google Instant 上线的那个时候,当输入搜索查询时,它会显示即时搜索结果。AJAX 驱动的自动完成功能风靡一时。 唯一的问题是,用户输入的速度通常快于 API 的自动完成搜索并返回响应的速度,从而导致一些奇怪的错误。这将触发竞争条件(race condition),在此情况下,较新的结果可能会被过期的所取代。 为什么会这样呢?因为每个 AJAX 成功处理程序都有权直接更新显示给用户的建议列表。最慢的 AJAX 请求总是可以通过盲目替换获得用户的注意,即使这些替换的结果可能是较新的。 -为了解决这个问题,我创建了一个建议管理器 —— 一个单一数据源去管理查询建议的状态。它知道当前有一个待处理的 AJAX 请求,并且当用户输入新内容时,这个待处理的 AJAX 请求将在发出新请求之前被取消,因此一次仅一个响应处理程序将能够触发 UI 状态更新。 +为了解决这个问题,我创建了一个建议管理器 —— 一个单一数据源去管理查询建议的状态。它知道当前有一个待处理的 AJAX 请求,并且当用户输入新内容时,这个待处理的 AJAX 请求将在发出新请求之前被取消,因此一次只有一个响应处理程序将能够触发 UI 状态更新。 -任何种类的异步操作或并发都可能导致类似的竞争条件。如果输出取决于不可控事件的顺序(例如网络,设备延迟,用户输入,随机性等),则会发生竞争条件。实际上,如果你使用共享状态,并且该状态依赖于因不确定性因素而变化的序列,总而言之,输出都是无法预测的,这意味着无法正确测试或完全理解。正如 Martin Odersky(Scala 语言的创建者)所说: +任何种类的异步操作或并发都可能导致类似的竞争条件。如果输出取决于不可控事件的顺序(例如网络,设备延迟,用户输入,随机性等),则会发生竞争条件。实际上,如果你正在使用共享状态,并且该状态依赖于一系列不确定性因素,总而言之,输出都是无法预测的,这意味着无法正确测试或完全理解。正如 Martin Odersky(Scala 语言的创建者)所说: -> 不确定性 = 并行处理 + 可变状态 +> **不确定性 = 并行处理 + 可变状态** 程序的确定性通常是计算中的理想属性。可能你认为还好,因为 JS 在单线程中运行,因此不受并行处理问题的影响,但是正如 AJAX 示例所示,单线程JS引擎并不意味着没有并发。相反,JavaScript 中有许多并发来源。API I / O,事件侦听,Web Worker,iframe 和超时都可以将不确定性引入程序中。将其与共享状态结合起来,就可以得出解决 bug 的方法。 @@ -127,7 +127,7 @@ Math.random(); // => 0.3550692005082965 那将每次都会产生相同的结果。当我们要求计算机产生一个随机数时,通常意味着我们想要一个与上次不同的结果。每一面都印着相同数字的一对骰子有什么意义呢? -有时我们必须询问计算机当前时间。我们不会详细的知道时间函数的工作原理。只需复制以下代码: +有时我们必须询问计算机当前时间。我们不会详细地了解时间函数的工作原理。只需复制以下代码: ``` const time = () => new Date().toLocaleTimeString(); @@ -175,7 +175,7 @@ highpass(5, 4); // false ## 不变性 -JavaScript的对象参数是引用的,这意味着如果函数要更改对象或数组参数上的属性,则将使该函数外部可访问的状态发生变化。纯函数不得改变外部状态。 +JavaScript 的对象参数是引用的,这意味着如果函数更改对象或数组参数上的属性,则将使该函数外部可访问的状态发生变化。纯函数不得改变外部状态。 考虑一下这种改变的,**不纯的** **`addToCart()`** 函数: @@ -294,9 +294,9 @@ EricElliottJS.com 的成员可以观看带有交互式代码挑战的视频课 --- -**埃里克·埃利奥特(Eric Elliott)**是一名分布式系统专家,并且是[《Composing Software》](https://leanpub.com/composingsoftware)和[《Programming JavaScript Applications》](https://ericelliottjs.com/product/programming-javascript-applications-ebook/)这两本书的作者。作为 [DevAnywhere.io](https://devanywhere.io/) 的联合创始人,他教开发人员远程工作和实现工作 / 生活平衡所需的技能。他建立并为加密项目的开发团队提供咨询,并为 **Adobe 公司、Zumba Fitness、《华尔街日报》、ESPN、BBC** 和包括 **Usher、Frank Ocean、Metallica** 在内的顶级唱片艺术家的软件体验做出了贡献。 +**埃里克·埃利奥特(Eric Elliott)** 是一名分布式系统专家,并且是[《Composing Software》](https://leanpub.com/composingsoftware)和[《Programming JavaScript Applications》](https://ericelliottjs.com/product/programming-javascript-applications-ebook/)这两本书的作者。作为 [DevAnywhere.io](https://devanywhere.io/) 的联合创始人,他教开发人员远程工作和实现工作 / 生活平衡所需的技能。他建立并为加密项目的开发团队提供咨询,并为 **Adobe 公司、Zumba Fitness、《华尔街日报》、ESPN、BBC** 和包括 **Usher、Frank Ocean、Metallica** 在内的顶级唱片艺术家的软件体验做出了贡献。 -**他与世界上最美丽的女人一起享受着远程的生活方式。** +**他与世界上最美丽的女人一起享受着远程办公的生活方式。** > 如果发现译文存在错误或其他需要改进的地方,欢迎到 [掘金翻译计划](https://github.com/xitu/gold-miner) 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 **本文永久链接** 即为本文在 GitHub 上的 MarkDown 链接。 From fb935402ea4164b8966ff91bc1b6b65e519d8138 Mon Sep 17 00:00:00 2001 From: niayyy Date: Fri, 27 Mar 2020 20:29:43 +0800 Subject: [PATCH 5/8] Update master-the-javascript-interview-what-is-a-pure-function.md --- .../master-the-javascript-interview-what-is-a-pure-function.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md index af56c4caa28..9746257d446 100644 --- a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md +++ b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md @@ -8,7 +8,7 @@ # 掌握 JavaScript 面试:什么是纯函数? ![Image: Pure — carnagenyc (CC-BY-NC 2.0)](https://cdn-images-1.medium.com/max/2048/1*gF8oCkYNvktBbAAG-nxYrg.jpeg) -纯函数对于实现各种目的是必不可少的,包括函数式编程,高并发和 React + Redux 构造的应用程序。但是纯函数是什么意思? +纯函数对于实现各种目的是必不可少的,包括函数式编程,可靠地并发和 React + Redux 构造的应用程序。但是纯函数是什么意思? 我们将通过来自 [《跟 Eric Elliott 学习 JavaScript》](http://ericelliottjs.com/product/lifetime-access-pass/) 的免费课程来回答的这个问题: From 7e606184ffbda692d461b3ebbfee3ba487e53fa7 Mon Sep 17 00:00:00 2001 From: niayyy Date: Sat, 28 Mar 2020 07:43:28 +0800 Subject: [PATCH 6/8] Update master-the-javascript-interview-what-is-a-pure-function.md --- ...ter-the-javascript-interview-what-is-a-pure-function.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md index 9746257d446..b27a2262f73 100644 --- a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md +++ b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md @@ -6,6 +6,7 @@ > * 校对者:[chaingangway](https://github.com/chaingangway)、[IAMSHENSH](https://github.com/IAMSHENSH) # 掌握 JavaScript 面试:什么是纯函数? + ![Image: Pure — carnagenyc (CC-BY-NC 2.0)](https://cdn-images-1.medium.com/max/2048/1*gF8oCkYNvktBbAAG-nxYrg.jpeg) 纯函数对于实现各种目的是必不可少的,包括函数式编程,可靠地并发和 React + Redux 构造的应用程序。但是纯函数是什么意思? @@ -16,11 +17,11 @@ #### 什么是函数? -**函数**是一个过程:它需要一些叫做**参数**输入,然后产生一些叫做**返回值**输出。函数可以用于以下目的: +**函数**是一个过程:它需要一些叫做**参数**的输入,然后产生一些叫做**返回值**的输出。函数可以用于以下目的: * **映射:**基于输入值产生一些的输出。函数把输入值**映射到**输出值。 * **过程化:**可以调用一个函数去执行一系列步骤。该一系列步骤称为过程,而这种方式的编程称为**面向过程编程**。 -* **I / O:**一些函数存在与系统其他部分进行通信,例如屏幕,存储,系统日志或网络。 +* **I/O:**一些函数存在与系统其他部分进行通信,例如屏幕,存储,系统日志或网络。 #### 映射 @@ -103,7 +104,7 @@ console.log( double(5) ); // 10 > **不确定性 = 并行处理 + 可变状态** -程序的确定性通常是计算中的理想属性。可能你认为还好,因为 JS 在单线程中运行,因此不受并行处理问题的影响,但是正如 AJAX 示例所示,单线程JS引擎并不意味着没有并发。相反,JavaScript 中有许多并发来源。API I / O,事件侦听,Web Worker,iframe 和超时都可以将不确定性引入程序中。将其与共享状态结合起来,就可以得出解决 bug 的方法。 +程序的确定性通常是计算中的理想属性。可能你认为还好,因为 JS 在单线程中运行,因此不受并行处理问题的影响,但是正如 AJAX 示例所示,单线程JS引擎并不意味着没有并发。相反,JavaScript 中有许多并发来源。API I/O,事件侦听,Web Worker,iframe 和超时都可以将不确定性引入程序中。将其与共享状态结合起来,就可以得出解决 bug 的方法。 纯函数可以帮助你避免这些 bug。 From c6c5f3dbeeef0006817ef3e7a168cb861e198bac Mon Sep 17 00:00:00 2001 From: niayyy Date: Sat, 28 Mar 2020 07:44:55 +0800 Subject: [PATCH 7/8] Update master-the-javascript-interview-what-is-a-pure-function.md --- .../master-the-javascript-interview-what-is-a-pure-function.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md index b27a2262f73..e0a629323be 100644 --- a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md +++ b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md @@ -71,7 +71,7 @@ console.log( double(5) ); // 10 因此, **`console.log( double(5) );`** 与 **`console.log(10);`** 相同 -这是真实存在的,因为 **`double()`** 是一个纯函数,但是如果 **`double()`** 有副作用,例如将值保存到磁盘或打印到控制台,用10 替换 **`double(5)`** 会改变函数的含义。 +这是真实存在的,因为 **`double()`** 是一个纯函数,但是如果 **`double()`** 有副作用,例如将值保存到磁盘或打印到控制台,用 10 替换 **`double(5)`** 会改变函数的含义。 如果想要引用透明,则需要使用纯函数。 From 819cbe02fea9116ab2734da908d06c859fc09cad Mon Sep 17 00:00:00 2001 From: lsvih Date: Sat, 28 Mar 2020 08:39:26 +0800 Subject: [PATCH 8/8] Update master-the-javascript-interview-what-is-a-pure-function.md --- ...cript-interview-what-is-a-pure-function.md | 22 +++++++------------ 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md index e0a629323be..664f3fa5c4b 100644 --- a/TODO1/master-the-javascript-interview-what-is-a-pure-function.md +++ b/TODO1/master-the-javascript-interview-what-is-a-pure-function.md @@ -29,7 +29,7 @@ **`Math.max()`** 以一组数字作为参数并返回最大数字: -``` +```js Math.max(2, 8, 5); // 8 ``` @@ -57,13 +57,13 @@ Math.max(2, 8, 5); // 8 现在让我们用 JavaScript 来描述这个函数: -``` +```js const double = x => x * 2; ``` 你可以使用 **`console.log()`** 检查函数输出: -``` +```js console.log( double(5) ); // 10 ``` @@ -116,7 +116,7 @@ console.log( double(5) ); // 10 考虑以下示例: -``` +```js Math.random(); // => 0.4011148700956255 Math.random(); // => 0.8533405303023756 Math.random(); // => 0.3550692005082965 @@ -130,7 +130,7 @@ Math.random(); // => 0.3550692005082965 有时我们必须询问计算机当前时间。我们不会详细地了解时间函数的工作原理。只需复制以下代码: -``` +```js const time = () => new Date().toLocaleTimeString(); time(); // => "5:15:45 PM" @@ -144,13 +144,13 @@ time(); // => "5:15:45 PM" **如果函数在给定相同的输入的情况下始终产生相同的输出,则该函数是纯函数**。你可能还记得代数课上的这个规则:相同的输入值将始终映射到相同的输出值。但是,许多输入值可能会映射到相同的输出值。例如,以下函数是**纯函数**: -``` +```js const highpass = (cutoff, value) => value >= cutoff; ``` 相同的输入值将始终映射到相同的输出值: -``` +```js highpass(5, 5); // => true highpass(5, 5); // => true highpass(5, 5); // => true @@ -158,7 +158,7 @@ highpass(5, 5); // => true 许多输入值可能映射到相同的输出值: -``` +```js highpass(5, 123); // true highpass(5, 6); // true highpass(5, 18); // true @@ -289,12 +289,6 @@ test('addToCart()', assert => { --- -## 在 EricElliottJS.com 上了解更多信息 - -EricElliottJS.com 的成员可以观看带有交互式代码挑战的视频课程。如果你还不是会员,[立即注册](https://ericelliottjs.com/). - ---- - **埃里克·埃利奥特(Eric Elliott)** 是一名分布式系统专家,并且是[《Composing Software》](https://leanpub.com/composingsoftware)和[《Programming JavaScript Applications》](https://ericelliottjs.com/product/programming-javascript-applications-ebook/)这两本书的作者。作为 [DevAnywhere.io](https://devanywhere.io/) 的联合创始人,他教开发人员远程工作和实现工作 / 生活平衡所需的技能。他建立并为加密项目的开发团队提供咨询,并为 **Adobe 公司、Zumba Fitness、《华尔街日报》、ESPN、BBC** 和包括 **Usher、Frank Ocean、Metallica** 在内的顶级唱片艺术家的软件体验做出了贡献。 **他与世界上最美丽的女人一起享受着远程办公的生活方式。**