人类可读的 JavaScript
长期以来,人类需要像机器一样“说话”才能与机器沟通。如今,情况依然如此,我们仍然需要使用汇编语言和其他低级语言的人才。但对我们许多人来说,这些复杂性已经被抽象化了。我们的工作是专注于人类可读的内容,并让机器解释我们的代码。
这种考虑在相同的代码可以用多种方式编写的情况下最为明显。所以今天,我不想讨论代码的工作原理,而是想谈谈它的可读性。这里还有另一篇文章是关于函数式 JavaScript 的,但我们假设我们讨论的是map
……
map
是 JavaScript 中可用于数组的函数。可以将其视为for each
。它接受一个函数作为参数,并让该函数运行数组中的每个元素。不同之处在于,它完全不会改变原始数组。结果是一个新数组。
例子
const arr = [1,2,3]
let multipliedByTwo = arr.map(el => el*2)
// multipledByTwo is [2,4,6]
好的,我们知道 map 的作用了。但请看上面的代码片段。这是一个极其简洁的函数,它将一个变量乘以 2。
那么让我们来看看编写相同逻辑的所有不同方法。
可选括号
我们可以做的第一个可选添加是在内部函数的参数定义中添加括号。这使得这段代码看起来更像一个典型的函数定义。
const arr = [1,2,3]
let multipliedByTwo = arr.map((el) => el*2)
有趣的是,我们不需要它们的唯一原因是我们只传递了一个参数。
const arr = [1,2,3]
let multipliedByTwo = arr.map((el, index) => el*2)
如果传递多个参数,括号是必须的。我们的例子是map
,如果是的话,reduce
我们总是会使用括号。
那么,让我们来评估一下。添加括号会有什么损失吗?会有什么好处吗?我们添加了两个字符,这传达了什么信息?这些都是我们在为团队成员以及未来的自己维护和阅读代码时需要问自己的问题。
花括号和return
我们可以更进一步,让内部函数遵循官方函数语法。这样做需要使用花括号和return
关键字。
const arr = [1,2,3]
let multipliedByTwo = arr.map((el) => { return el*2})
我们现在对这段代码有什么感觉?作为函数,它读起来确实更清晰。括号和return
代码块是否显得更臃肿?我们对这段代码的看法会根据返回的逻辑而改变吗?
事实证明,如果我们的函数逻辑多于一行,那么这又是非可选的。
const arr = [1,2,3]
let multipliedByTwo = arr.map(
(el) => {
if(el%2 === 0) {
return el*2
} else {
return el+1
}
})
有意思。我们对额外字符的看法会根据用例而改变吗?这对我们整个代码的一致性意味着什么?
使用单独的函数
正如我们所知,map
它接受一个函数作为参数,并将数组中的每个元素传递给它。也许我们可以,或者应该,在它之外定义我们的内部逻辑map
。目前来看,它看起来有点像金字塔代码。
const arr = [1,2,3]
const timesTwo = (el) => el*2
let multipliedByTwo = arr.map((el) => timesTwo(el))
我们怎么想?实际上,它的字符数几乎和原版一样。但是,如果上面的示例逻辑更复杂,情况又会怎样呢?
const arr = [1,2,3]
const timesTwoOrPlusOne = (el) => {
if(el%2 === 0) {
return el*2
} else {
return el+1
}
}
let multipliedByTwo = arr.map((el) => timesTwoOrPlusOne(el))
这是否改变了你的看法?还是说它看起来杂乱无章、重复乏味?
只是一个函数
函数式编程是一种有趣的范式。部分原因在于它允许我们编写代码的方式。我们再次想起它map
接受一个函数作为参数。那么为什么不给它一个函数呢?
const arr = [1,2,3]
const timesTwo = (el) => el*2
let multipliedByTwo = arr.map(timesTwo)
是的,这是有效的。map
它知道将获取到的元素传递给函数并使用结果。我们可以通过确定函数可能采用的形式来进一步了解细节timesTwo
。目前,它只是一行简洁的代码。
请注意,这map
真的很聪明。即使该函数现在同时使用元素和索引来获取返回值,我们也可以传递相同的函数!
const arr = [1,2,3]
const timesTwoPlusIndex = (el, index) => (el*2) + index
let multipliedByTwo = arr.map(timesTwoPlusIndex)
这看起来可读性强吗?multipledByTwo
阅读起来确实很舒服,但它timesTwoPlusIndex
在我们的代码库中位于哪里?很难追踪吗?如果有人第一次看到这个,他们知道这是一个函数吗?还是他们会假设它是一个对象或数组变量?
函数是 JavaScript 中的对象,但暂时忽略这种重复。
我们如何确定什么是可读的
没有一种语法适合所有情况。你的目标用户是谁?多语言人士还是 JavaScript 专家?谁在维护你的代码?有多少人使用这个代码库?所有这些都很重要。
这完全取决于用例,一致性很重要。然而,看到同一功能有如此多的不同表现形式,确实令人大开眼界。所有这些示例都将构建到相同的精简代码中。因此,对于我们开发者来说,决策是基于人类可读性的,完全没有考虑机器性能和功能。
我提出了很多问题,但答案不多。我有自己的观点,但也很想听听你的意见。这些版本中哪些最易读?有没有你更喜欢的版本?我们下面讨论一下!
文章来源:https://dev.to/laurieontech/ human-read-javascript-337o