原文发布与个人博客 lambdas.dev。编程
摸鱼时更新。api
好的代码不只是在性能、体积、内存,更要 code for humans
。数组
咱们知道代码被人阅读的难度远胜于引擎,要写出好的代码须要脱离本身的视角,以他人的眼光审视,从新理解上下文含义, 此时代码的架构、拆分、组合、技巧则给予人阅读的幸福感,咱们致力于构建优秀的代码意味着不只以代码为工具,更是将其视做传达智慧、 思想、理念的桥梁。这是一种智慧上的锤炼与分享。缓存
const
。const
在 JavaScript 中不只能够用于命名常量,由于其用于保证内存地址不可变,因此也经常使用于声明对象与数组。在编程中多使用 const
代替 let
, 能够在风格上向 immutable
靠拢,在编程思惟上开始摈弃反作用。更多的使用 const
虽然可能使声明项增多,但对于开发者来讲,更少的心智负担和语义化 命名会使代码质量大大上升。性能优化
在 JS 中若是过多的使用 let
声明变量,阅读者每每须要贯穿上下文反复阅读才能理解当前变量的值,且变量可能被其余函数引用更改,显而易见, 使用变量越多理解的成本也就越高,并且你很难追踪变量具体的值。以下方代码统计数组每一个值的总和。使用 const
命名一个常量后, 你将没法使用 forEach
在每一次循环时改动它,转而使用 reduce
,咱们减小了变量 count
,增长了常量 count
,在随后代码的引用中就无需担心 变量的状态,由于咱们知道,count
只能是一个数值,而不会变化。架构
// bad
let count = 0
[...].forEach(item => {
count += item
})
// good
const count = [...].reduce((pre, current) => pre + current, 0)
复制代码
配合上文所提到的 const
,咱们可以使用函数表达式来建立一个函数,更多的时候咱们会与箭头函数配合食用 const f = () => {}
。它们优于传统函数声明的地方在于:函数
this
的思惟依赖。// bad
function addOne(value) {
return value + 1
}
// good
const addOne = value => value + 1
复制代码
缩进问题在 JS 代码中更广泛,推荐在可能的代码块中使用 return
优先返回,如 function
if else
等语句。这样能够有效的减小缩进,同时也能使 代码更加的清晰可读,由于在同一时间内老是只作一件事。工具
咱们还能够在必要时优先 return
较短的语句,使代码更美观。post
// bad
const render = () => {
if (isServer) {
// server code
} else {
// client code
}
}
// good
const render = () => {
if (isServer) return // server code
// client code
}
复制代码
若是你不是编写类库、底层代码等对性能要求极为苛刻时,请勿过分优化性能。绝大多数没必要要的性能优化会使代码可读性急剧降低。这很是重要。性能
例 1,没必要要的减小内存空间
// bad
let fullname
users.forEach(user => {
fullname = user.firstname + user.lastname
// ...
register(fullname)
})
// good
users.forEach(user => {
const fullname = user.firstname + user.lastname
// ...
register(fullname)
})
复制代码
例 2,没必要要的运算优化
// bad
let len = users.length
for (i = 0; i < len; i ++) {}
// good
users.forEach(user => {})
复制代码
魔术字符 (魔术数字) 指的是代码中出现意义不明的字符,从上下文没法推论其来源与做用,这会使代码难以扩展。
一般,咱们还会把全部的字符或数字统一声明在一个常量文件内,如 host
defaultSettings
port
等等,这会有益于维护。
// bad
const url = `${host}/2/users`
// good
const apiVersion = 2
const apis = {
users: 'users',
projects: 'projects',
// ...
}
const url = `${host}/${apiVersion}/${apis.users}`
复制代码
在不断延展的需求中,咱们的函数会有愈来愈多的参数,但要注意,当一个函数的参数较多时会使调用方困扰。咱们并不是须要全部的函数都实现 curry
,但减小 函数参数、合并参数、分离函数都会显著提高代码的可读性与扩展性。
在调用较多参数的函数时,咱们不只要紧记每一个参数的顺序,还要对空缺的参数进行补位 (如传入 null
undefined
等),这会致使声明与调用的代码中都被迫 存在很是多的变量与判断。在函数个数增加时能够考虑将其中的一部分合成为一个对象参数,或是将一部分功能拆离,做为一个新的函数。
// bad
const createUser = (id, name, createdAt, telephone, email, address) => {}
// good
const createUser = (id, userOptions) => {}
复制代码
在一个函数中组好只作一件事,同时也最好保证这件事是与函数的名称是相关的。在单个函数中累积逻辑会给阅读者带来很是大的心智负担,若是咱们予以函数拆分、 合理化的命名、组合,就能使代码总体得到极大的美感,看起来层次分明,泾渭分明。
// bad
const getUser = id => {
const headers = // ...
const options = // ...
options.headers = headers
const host = // ...
const url = // ...
if (id.length > 1) // ...
return fetch(url, options)
}
// good
const makeOptions = () => {}
const makeUrl = id => {}
const getuser = id => {
const options = makeOptions()
const url = makeUrl(id)
return fetch(url, options)
}
复制代码
过长的条件判断经常会在一段时间后变的匪夷所思,很难理解其中的逻辑,将其使用语义化的常量代替则可向阅读者提示意义,更省略了没必要要的注释。
// bad
// the code for teen-ager
if (user.age < 19 && user.age > 13) {
// ...
}
// good
const isTeenAgerMember = user.age < 19 && user.age > 13
if (isTeenAgerMember) // ...
复制代码
减小函数的反作用并不是老是须要以纯函数来解决全部问题,没必要慌张,咱们知道反作用会使状态的变化难以琢磨,在编程中应当以较少的反作用函数为目标, 使函数的预期与实际保持一致的同时不至于形成过多的影响,这或许会使在构思和声明时花费一些时间,但对上下文的代码块来讲,是一件好事。
你可能发现有些时候会不可避免的改变了某些外部状态,好比缓存某些值,为此你陷入了重构的苦思,事实是没必要过于担心,你想作的就必然有道理。这就是 编程中的取舍 。学会在编程、架构、工程上有所取舍 (不是为所欲为) 后构建出的产品天然会嵌上独具一格的风采,这就是你的编程。
// bad
let user = getUser()
const upload = () => {
user.name = `${user.name}-upload`
// fetch user ...
}
// good
const user = getUser()
const upload = user => {
const body = Object.assign({}, user, { name: `${user.name}-upload` })
// fetch body ...
}
upload(user)
复制代码