码修
2019 年 7 月 15 日
这篇文章, 主要介绍 JavaScript 的编程小范式小技巧, 其中一些小技巧是我的工作切身经验所得, 一些是从同事身上偷来的宝贵知识.
简单记录以下经验, 排名不分先后.
1. Early exits 提前退出
- function transformData(rawData) {
- // check if no data
- if (!rawData) {
- return [];
- }
- // check for specific case
- if (rawData.length == 1) {
- return [];
- }
- // actual function code goes here
- return rawData.map((item) => item);
- }
我将这种模式称为 "早期退出", 但有些人也将此称为 "保镖模式" 或 "保护条款". 除了命名之外, 该模式首先采用检查无效用例并从该函数返回的方法, 否则它继续到函数的预期用例并执行.
对我来说, 这种方法有一些我非常喜欢的积极因素:
鼓励思考无效 / 边缘情况以及如何处理这些情况
避免意外和不必要的代码处理意外用例
在心理上允许我更清楚地处理每个用例
一旦采用, 您可以快速浏览功能并了解流程和执行情况, 这通常遵循自上而下的方法 - 无效情况 ->小案例 ->预期案例
更多信息:
Rik Schennink 的保镖模式
2. Switch case 语句转换成对象字面量 (Switch to object literal)
- // 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 语句有很多的弊端, 我写 case 语句经常会忘记写 break, 而且 switch 语句代码量比较大.
我更喜欢使用对象字面量, 这就是为什么:
不必担心 case 或 break
更容易阅读并快速了解代码的含意
对象字面量写起来比较轻松
更少的代码
更多信息:
切换案例, if else 或 May Shavin 的循环图
用 Todd Motto 替换带有对象文字的 switch 语句
重写 JavaScript: 替换 Chris Burgin 的 Switch 语句
3. 一个循环生成两个数组(One loop two arrays)
- 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;
- }, [[], []]);
以上代码是通过一个循环把一个数组分成两个数组: 大于 10 的值以及小于 10 的值.
这种模式在代码层面并没有什么特殊的技巧, 你稍微认真读一下代码就知道怎么实现, 但是它确实非常好用.
这段代码有一个名字(bifurcate), 我从 https://30secondsofcode.org/#bifurcate 偷学的. 如果您从未浏览过该网站, 我建议您去看看, 有好多的信息和有用的代码.
我知道 reduce 可能有点令人生畏, 并且不是很清楚发生了什么, 但是如果你能够熟悉它, 你可以真正利用它来构建循环收集时所需的任何数据结构. 他们真的应该把它叫做 builder 而不是 reduce.
更多信息:
https://30secondsofcode.org/
4. 没有 foo 变量(No 'foo' variables)
- // bad
- const foo = y && z;
- // good
- const isPostEnabled = isPost && postDateValid;
这里要讨论的是代码规范.
这个看起来有点明显, 但我确信我们都看到过这样做的代码. 花点时间, 尽力给出恰当的名字.
变量命名应该用于帮助解释和给出代码中发生的事情的上下文.
有人应该能够阅读你的代码, 然后开始理解想要解决的问题.
更多信息:
Richard Tan 命名变量的艺术
5. 嵌套三元运算符(Nested ternaries)
- 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 语句来实现嵌套的条件判断, 第二部分是用 嵌套的三元运算来实现复杂的条件判断.
写文章的老哥觉得第二部分比第一部分好, 我也认同.
但是第二部分, 我也很难读懂啊. 原因是只要是逻辑本身复杂了, 就会很难读懂, 所以我觉得, 最好还是能拆分就拆分, 或许可以考虑一下前文说的对象字面量.
更多信息:
埃里克. 艾略特 (Eric Elliot) 的嵌套三元组很棒
来源: http://www.mzh.ren/five-programming-patterns-i-like.html