30

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

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

提前退出(early exits)

function transformData(rawData) {
  // check if no data
  if (!rawData) {
    return [];
  }

  // check for specific case
  if (rawData.length == 0) {
    return [];
  }

  // actual function code goes here
  return rawData.map((item) => item);
}

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

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

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

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

2. 用对象字面量替代 Switch

// Switch
let createType = null;
switch (contentType) {
  case "post":
    createType = () => console.log("creating a post...");
    break;
  case "video":
    createType = () => console.log("creating a video...");
    break;
  default:
    createType = () => console.log('unrecognized content type');
}

createType();

// Object literal
const contentTypes = {
  post: () => console.log("creating a post..."),
  video: () => console.log("creatinga  video..."),
  default: () => console.log('unrecognized content type')
};

const createType = contentTypes[contentType] || contentTypes['default'];
createType();

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

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

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

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

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

  arrays[1].push(exampleValue);
  return arrays;
}, [[], []]);

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

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

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

4. 不要用 foo 做变量

// bad
const foo = y && z;

// good
const isPostEnabled = isPost && postDateValid;

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

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

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

更多信息:The art of naming variables

5. 嵌套三元运算符

// 之前
let result = null;
if (conditionA) {
  if (conditionB) {
    result = "A & B";
  } else {
    result = "A";
  }
} else {
  result = "Not A";
}
// 改造后
const result = !conditionA
  ? "Not A"
  : conditionB
  ? "A & B"
  : "A";

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

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

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

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

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

如果对你有帮助,请关注【前端技能解锁】:
qrcode_for_gh_d0af9f92df46_258.jpg


戎马
2.4k 声望346 粉丝

前端码农一枚,上班一族,爱文学一本。ส็็็็็็็็็็็็็็ ส้้้้้้้้้้้้้้้้้้้。