[关闭]
@wy 2019-07-18T22:56:49.000000Z 字数 2441 阅读 487

我喜欢的5种编程技巧

翻译


在这篇文章中,我介绍了一些编程时尝试使用的模式。这些模式是多年来我自己在工作中实践的结果,也有是从同事那里偷偷学到的。

这些模式没有特定的顺序,只是一个简单的集合。

提前退出(early exits)

  1. function transformData(rawData) {
  2. // check if no data
  3. if (!rawData) {
  4. return [];
  5. }
  6. // check for specific case
  7. if (rawData.length == 1) {
  8. return [];
  9. }
  10. // actual function code goes here
  11. return rawData.map((item) => item);
  12. }

我将这种模式称为“提前退出(early exits)”,但有些人也将此称为“保镖模式(the Bouncer Pattern)”或“保护条款('guard clauses)”。撇开命名不谈,该模式采用的方法是首先检查无效的情况,然后从该函数返回,否则它将继续使用该函数的预期情况并执行。

对我来说,这种方法有一些我非常喜欢的优点:

  1. 有助于思考无效和边界情况,以及在这种情况下该如何处理。
  2. 避免对意外情况进行意外和不必要的代码处理
  3. 这样使我更能清楚地处理每种情况
  4. 一旦使用这种方式,您就可以快速地浏览函数并理解流程和执行,这通常遵循自顶向下的方法,即从无效的情况—>小情况—>预期情况。

更多信息:保镖模式(the Bouncer Pattern)

2. 用对象字面量替代 Switch

  1. // Switch
  2. let createType = null;
  3. switch (contentType) {
  4. case "post":
  5. createType = () => console.log("creating a post...");
  6. break;
  7. case "video":
  8. createType = () => console.log("creating a video...");
  9. break;
  10. default:
  11. createType = () => console.log('unrecognized content type');
  12. }
  13. createType();
  14. // Object literal
  15. const contentTypes = {
  16. post: () => console.log("creating a post..."),
  17. video: () => console.log("creatinga video..."),
  18. default: () => console.log('unrecognized content type')
  19. };
  20. const createType = contentTypes[contentType] || contentTypes['default'];
  21. createType();

接下来就是要移除 Switch。在写 case 的时候我经常会犯错误,也会忘记写 break,这会引起各种有趣的问题。当我编写代码时,switch语句并没有体现太多的价值。

我更喜欢使用对象字面量,原因如下:

  1. 不用担心 cacebreak
  2. 更容易阅读并快速了解正在发生的事情
  3. 对象字面量很容易写
  4. 代码量少

3. 用一次循环处理两个数组

  1. const exampleValues = [2, 15, 8, 23, 1, 32];
  2. const [truthyValues, falseyValues] = exampleValues.reduce((arrays, exampleValue) => {
  3. if (exampleValue > 10) {
  4. arrays[0].push(exampleValue);
  5. return arrays;
  6. }
  7. arrays[1].push(exampleValue);
  8. return arrays;
  9. }, [[], []]);

这种模式没什么特别的,我应该早点意识到,但我发现自己过滤一组元素,以获得所有匹配特定条件的元素,然后在另一种情况下要再做一次。这意味着对一个数组进行两次循环,但我可以只做一次。

原来它有一个名字(bifurcate),我从 30secondsofcode.org借鉴过来的。如果你从未去过那个网站,我建议你去那里。有很多有用的信息和代码。

我知道 reduce 可能会让人望而生畏,也不太清楚会发生什么,但如果你能适应它,在遍历集合时,您可以真正利用它来构建所需的任何数据结构。他们应该叫它 builder 而不是 reduce

4. 不要用 foo 做变量

  1. // bad
  2. const foo = y && z;
  3. // good
  4. const isPostEnabled = isPost && postDateValid;

这看起来很明显,但我相信我们都见过这样做的代码。花点时间,尽你最大的努力取个合适的名字。

这对于在职的专业人士或处于教育他人位置的人来说尤其重要。应该使用变量命名来帮助解释,在代码的上下文中发生了什么事情。

别人能够在阅读您的代码时,并大致可以理解要解决的问题。

更多信息:The art of naming variables

5. 嵌套三元运算符

  1. // 之前
  2. let result = null;
  3. if (conditionA) {
  4. if (conditionB) {
  5. result = "A & B";
  6. } else {
  7. result = "A";
  8. }
  9. } else {
  10. result = "Not A";
  11. }
  12. // 改造后
  13. const result = !conditionA
  14. ? "Not A"
  15. : conditionB
  16. ? "A & B"
  17. : "A";

我承认,一开始,使用嵌套三元运算符的想法的确令人倒胃口。它看起来是一种编写条件的巧妙方式。

然后我开始编写业务逻辑,发现自己使用了嵌套的 if else 语句和一些非常可疑的条件逻辑。

我认为使用 ifelse更容易阅读,因为它们是实际的单词,有语义化,但当它们嵌套后,我开始很难理解发生了什么,并在心里默默跟踪所有情况。

我认为这种模式取决于你、你的团队的偏好。我在代码库中也很好的使用这种方式。当然使用三元运算符具有两面性,但就我个人而言,嵌套三元运算符真的越来越吸引我了。

更多信息:Nested Ternaries are Great by Eric Elliot

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注