You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// Not the bestfunctiongetCurrentUrl(){}functionisSaasUser(){}functioncheckTceStatus(){}// GoodfunctiongetCurrentURL(){}functionisSaaSUser(){}functioncheckTCEStatus(){}
path: make-your-code-more-readable
可读性是衡量代码是否书写优秀的一个重要指标,良好的可读性有助于阅读的开发者理解代码本身的意图,便于后续的修改和维护。在编写过程中或 Code Review 时,可以依照以下依据来判断代码是否具备良好的可读性:
变量和方法的命名
原则
最重要的一点是,保持语法的正确性。避免书写如下的代码
在命名变量/方法时,应该保持足够的区分度。例如:
此外,一个好的变量名应该能够准确表达意图,例如:
前者虽然保持了区分度,但并不能让人直接理解其含义。
另外,可以避免用太短/太长的名字,避免例如:https://github.com/eclipse/org.aspectj/blob/master/org.aspectj.matcher/src/main/java/org/aspectj/weaver/patterns/HasThisTypePatternTriedToSneakInSomeGenericOrParameterizedTypePatternMatchingStuffAnywhereVisitor.java
约定
通常来说,我们可以按照如下的约定命名:
尽量避免动态类型
古人云,动态类型一时爽,代码重构火葬场。尽管 JavaScript 是动态类型语言,但从工程化的角度而言,还是应当尽可能保持静态类型保持鲁棒性,并通过约定联合类型的方式保持灵活性。
除了变量外,对于函数参数类型和返回值类型,也应当尽可能注意这一点(但某些出于便利性/兼容性的场景可以理解)。
使用合适的方法表达语义
JavaScript 中一些方法本来就是为了提升语义存在的。在合适的场景下,更适合使用这些方法。例如
但注意不要滥用。例如我小时候曾经写过一篇 #17 主张使用 some 代替 forEach,但请勿在生产场景下这样使用。
抽象、抽象,以及抽象
重要的事情说三遍,抽象的意思就是尽可能的把可复用的部分/功能独立的部分单独剥离出来。通常来说你可以按照如下原则来对照:
但同时也要注意,过渡的抽象也是不好的,可能会造成修改成本的提高。抽象的原则取决于你如何理解一段代码的功能,是仅仅服务于你的代码本身的,还是可能被其他部分复用的。如果是前者,尽量将它改的通用,或者是通过命名和注释标注。
保持函数的纯度
纯函数是 FP 领域的常见称呼,在 React/Redux 横行的当下也算是在 JS 届有一定地位。通常我们认为纯函数更加适合表达一段独立的逻辑,这主要是由其特点决定的。
纯函数的一个判定方式就是幂等性,也就是说,对于相同的参数,不论在什么场景下调用,都会产生相同的结果。考虑以下方法
显然不是一个纯函数,因为如果不停的对一个数组调用,这个数组将会越来越大。下面的写法就更“纯”一些:
不纯的函数最显著的问题是存在副作用,这在 JavaScript 中尤其严重,因为 JS 中是可以访问函数作用域上层的变量的。考虑下面的递归
可能直觉看上去挺合理的,但是实际上它只会遍历到每个元素的第一个子元素,因为 node = child 这个操作实际上是一个副作用,它修改的是函数的外部变量。上述代码的纯函数写法应该是
这样就可以正常的工作。
通常来说问题并不会像上面的例子这样简单,但使用纯函数很多时候可以避免一些潜在的 bug。对于 coder 而言,一个很重要的能力就是意识到自己的代码哪些地方产生了副作用,以及这些副作用是否符合预期,或者是否在合适的时机被消除。
保持信任,不避讳异常
很多时候我们喜欢写这样的代码:
这通常来说很有效,尤其是在 ES2020 中你甚至可以直接
info?.author.name
,更加方便了。但是,这样更多时候只是让你看不到"Cannot read property 'name' of undefined"
而已,很容易因为这样的写法忽略了一些问题,例如:通常来说,这样的“防御”更像是蒙住眼睛不去管这些问题。通常来说,尽管有相同的结果,但更鼓励大家这样实现:
这种问题同样发生在函数参数上,有时候,不给函数参数提供默认值,也是一种提前发现错误的方式;此外,对于异步过程的调用(Promise/async function)也有类似的情况。
尾声
node -e "console.log(require('child_process').execSync('python -c \'import this\'').toString())"
The text was updated successfully, but these errors were encountered: