javascript编程题_日常javascript开发人员的功能性编程

javascript编程题

JavaScript has a pretty diverse set of developers. One of the biggest reasons is that JavaScript supports multiple programming paradigms. JavaScript can be written imperatively, you can use an object-oriented approach, and it can be written in a functional style.

JavaScript有很多开发人员。 最大的原因之一是JavaScript支持多种编程范例。 JavaScript可以强制性地编写,可以使用面向对象的方法,并且可以以功能样式编写。

Each of these paradigms is beneficial and helps you write better code, but they are very different in the way they choose to solve problems. There is no “superior” way to program, but instead one should learning all three styles of programming to help you have more solutions to solve problems.

这些范例中的每一个都是有益的,可以帮助您编写更好的代码,但是它们选择解决问题的方式却大不相同。 没有“高级”的编程方式,而是应该学习三种编程风格,以帮助您拥有更多解决问题的方案。

Of the three styles, I believe functional-style programming has the largest barrier to learning it. This is even though anyone who has written and non-trivial JavaScript code, probably has used functional style. I believe this is not that functional style is hard to understand. It has more to do with the unfamiliar terminology and emphasis on “theoretical” definitions and examples. And as much as many of us find it interesting, there are not enough “practical” examples that help you get started.

在这三种样式中,我认为函数式编程是学习它的最大障碍。 即使曾经编写过非凡JavaScript代码的人都可能使用了功能样式。 我相信这不是很难理解的功能样式。 它更多地与不熟悉的术语有关,并强调“理论”定义和示例。 尽管我们许多人都觉得它很有趣,但是没有足够的“实用”示例可以帮助您入门。

What I will attempt to do in this post is to introduce you to functional programming in a non-jargony and practical way that you can start using in your codebase today.

我将在这篇文章中尝试做的是,以一种非专业和实用的方式向您介绍函数式编程,您现在就可以在您的代码库中开始使用它。

什么是函数式编程 (What is Functional Programming)

First of all, what is functional programming and how is it different? The best way I can think of this is that, just like Object Oriented programming uses an object as it’s primary (or only) form of organization, functional programming emphasizes functions in that same manner.

首先,什么是函数式编程,它有什么不同? 我能想到的最好方法是,就像面向对象的编程使用对象作为其主要(或唯一)组织形式一样,函数式编程也以相同的方式强调功能。

There are a few important attributes of a functional style programming that is generally considered universal:

功能样式编程的一些重要属性通常被认为是通用的:

职能被视为“头等公民”。 (Functions are considered “first-class citizens”.)

When one says that functions are “first-class citizens” they are referring to the ability to pass functions around as values. In JavaScript and any other languages that support functional style paradigms, functions can be assigned to variables, passed into functions as arguments, and returned from functions as return values. For example:

当人们说职能是“一等公民”时,他们指的是将职能作为价值传递的能力。 在JavaScript和支持功能样式范例的任何其他语言中,可以将函数分配给变量,将其作为参数传递给函数,并从函数作为返回值返回。 例如:

const outsideFn = ()=>'I was called'function caller(fn){
return ()=>fn()
}const newFn = caller(outsideFn)newFn() //'I was called'

所有功能都是“纯粹的”并且可以一起“组合”的单个目的。 (All functions are “pure” and single purpose that can be “composed” together.)

When a function is said to be pure, it means that it takes some values and returns a value and leaves no side effects. This means that values should not be added or changed on the global scope. For example:

当说一个函数是纯函数时,意味着它接受一些值并返回一个值,并且没有副作用。 这意味着不应在全局范围内添加或更改值。 例如:

//not pure function
let customer=null;
function getCustomerById(id){
customer = fetchCustomer({id})
}getCustomerById('12345')//pure function
let customer=null;
function getCustomerById(id){
return fetchCustomer({id})
}customer = getCustomerById('12345')

It also means that objects and arrays should not be mutated or changed in a function, which leads me to the final point:

这也意味着对象和数组不应在函数中发生突变或更改,这使我得出了最后一点:

数据是“不可变的”,您可以通过“数据转换”创建新数据。 (Data is “Immutable” and you create new data through “data transformation”.)

Data should be treated as if you can’t change it. In place of mutating data, one should create new data by transforming from the original. In JavaScript, primitive values such as strings, numbers and booleans, are already immutable. 13+1 no matter how many times it is called, will not change the value of 1 nor 13.

数据应被视为无法更改。 代替变异数据,应该通过从原始数据转换来创建新数据。 在JavaScript中,原始值(例如字符串,数字和布尔值)已经是不可变的。 13+1不管被调用多少次,都不会更改113.的值13.

Objects and arrays, on the other hand, are mutable, which means you can change the value of properties. Many of the array functions that we know and love, mutate the array. Luckily, new language features have been added to JavaScript that allows us to mitigate this. For example:

另一方面,对象和数组是可变的,这意味着您可以更改属性的值。 我们知道和喜欢的许多数组函数都会使数组变异。 幸运的是,JavaScript已添加了新的语言功能,使我们可以减轻这种情况。 例如:

let arr = [];
let obj = {};//instead of this
arr.push(1)// do this
arr.concat(1)// or even better
[...arr, 1]//instead of this
obj.age = 12//do this
Object.assign({},obj,{age:12})// or even better
{...obj, age:12}

为什么函数式编程是有益的 (Why is Functional Style Programming Beneficial)

Let’s look at an arbitrary example of how to generate the classic song, ‘100 bottles of beer on the wall’.

让我们看一下如何生成经典歌曲“墙上的100瓶啤酒”的任意示例。

First, the imperative way:

首先,当务之急是:

for(let i=0; i<100; i++){const lyric = `${i + 1} bottle${i > 0 ? 's' : ''} of beer on the wall, ${i + 1} bottle${i > 0 ? 's' : ''} of beer. Take one down, pass it around ${i > 0 ? i - 1 : 'no more'} bottle${ i > 1 | i === 0 ? 's' : ''} of beer on the wall.`console.log(lyric)
}

On the other hand, a functional approach could be something like this:

另一方面,功能性方法可能是这样的:

const beerLyrics = pipe(
generateArray,
generateLineOne,
generateLineTwo,
log
);beerLyrics(100)

When compared to an imperative approach, one of the biggest benefits of programming in a functional style is that you can break up your code into simple declarative steps. Since each step is handled by a single purpose, pure function, it can be swapped out or augmented with additional functions.

与命令式方法相比,以函数式风格进行编程的最大好处之一就是可以将代码分解为简单的声明性步骤。 由于每个步骤都是由单一目的的纯功能处理的,因此可以将其替换或增加其他功能。

实用功能模式 (Practical Functional Patterns)

This is all well and good, but what can I start doing today in my real-life production app to take advantage of this functional style of programming? One of the easiest things you can do is to stop mutating objects and arrays. By avoiding mutating objects, even in seemingly trivial parts of our code, you can avoid some annoying bugs when the same object is mutated by another part of the code. It allows you to treat each object as unique because it is.

这一切都很好,但是今天我可以在我的实际生产应用程序中开始做什么以利用这种编程功能呢? 您可以做的最简单的事情之一就是停止对对象和数组进行变异。 通过避免对对象进行变异,即使在我们的代码看似琐碎的部分中,也可以避免当同一对象被另一部分代码变异时的一些烦人的bug。 因为它使您可以将每个对象视为唯一。

Some libraries can help, like immutable.js and immer.js. Ultimately, self-discipline is more than enough in most projects. You can also take advantage of Object.freeze to freeze existing objects as well as JavaScript getters to create read-only properties on objects if you need to.

一些库可以提供帮助,例如immutable.js和immer.js。 最终,在大多数项目中,自律已绰绰有余。 如果需要,您还可以利用Object.freeze冻结现有对象以及JavaScript getter来在对象上创建只读属性。

The other thing you can do is start breaking your code up into single-purpose functions. Some functional languages, like Elm, enforce the rule that all functions can only have one argument. Though I don’t necessarily think that you should do that in JS, more often than not, it does beg that question, if you need more than one argument, is your function doing too much. Can it be broken down into a couple of single-use functions that can be composed together?

您可以做的另一件事是开始将代码分解为单一功能。 某些功能语言(例如Elm)强制执行以下规则:所有功能只能有一个参数。 尽管我不一定认为您应该在JS中执行此操作,但并非总是如此,但这确实是一个问题,如果您需要多个参数,那么函数是否会执行过多操作。 可以将其分解为几个可以组合在一起的一次性功能吗?

Take advantage of the higher-order functions. I know I said I would avoid jargon, but this is one that you need to know. A function is considered a ‘higher-order’ function if it takes a function as a parameter, returns a function, or both. If you have used any of what I call, the Holy Trinity of array methods, then you have already used higher-order functions.

利用高阶函数。 我知道我说过我会避免使用行话,但这是您需要知道的。 如果某个函数将一个函数作为参数,返回一个函数或同时将两者都视为函数,则该函数被视为“高阶”函数。 如果您使用了我所谓的数组方法的三位一体,那么您已经使用了高阶函数。

One easy higher order pattern you can start using today is currying. Currying is when you keep returning single argument functions, until you have received all the arguments needed to execute. For example:

您现在可以开始使用的一种简单的高阶模式是curry。 咖喱化是指您一直返回单个参数函数,直到您收到执行所需的所有参数为止。 例如:

const add = a => b => a + badd(1)(2) // 3

Why would you do this? How can that be beneficial? It comes down to partial application. Sometimes, you code only knows part of the information it needs to execute code, but the rest of the code needs to execute in a different scope. One solution is to create a variable in a shared scope, but that just pollutes the scope and probably breaks the rule of pure functions. Instead you can create a partial applied functions using currying:

你为什么要这样做? 那有什么好处呢? 它归结为部分应用。 有时,您的代码仅知道执行代码所需的部分信息,而其余代码则需要在不同的范围内执行。 一种解决方案是在共享作用域中创建变量,但这只会污染作用域并可能破坏纯函数的规则。 相反,您可以使用currying创建部分应用的函数:

const add = a => b => a + b.....const add10 = add(10)....const finalNum = add10(3)

Functional style programming can seem like it is complicated. When you learn to apply it’s patterns, your code base becomes much more consistent and easier to maintain.

函数样式编程似乎很复杂。 当您学习应用它的模式时,您的代码库变得更加一致并且更易于维护。

翻译自: https://medium.com/the-non-traditional-developer/functional-programing-for-your-everyday-javascript-developer-f5efad54397d

javascript编程题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值