【如诗般写代码】你甚至连注释都没玩明白

引言

要问我认为最难的事是什么,那只有维护前人的代码。

我经常能看见一个文件里,写上百行,没有几个函数,没有注释,没有换行,

一头扎进去,闷头写到天昏地暗的

什么修复bug,提升性能之类的都不是事,会用调试工具和分时渲染就够了


注释篇

  1. 利用注释在编辑器开启代码提示

    看到区别了吗,左边用的是文档注释 ,鼠标悬浮能看到变量描述

    右边用的是行内注释,没有任何作用

    初步认识了文档注释的好处后,很多人可能还是不用,因为嫌麻烦。

    所以编辑器也为你着想了,以 VSCode 为例,输入 /**,就会自动生成文档注释

    如果在函数上面,再按下回车,还能补齐函数参数文档,如下图所示


  1. 利用文档注释描述函数功能

    当我鼠标悬浮在函数上时,就能看到他的各种描述,从其他文件导入也有效


  1. 智能提示当前参数描述,以及类型等

    这里也能用快捷键呼出,详见我上篇文章:# 【最高效编码指南】也许你不会用VSCode | IDEA


  1. 添加 JS 类型,实现类似 TS 的效果

    这里我呼出代码提示,但是他并没有给我补全任何方法,因为他不知道你的类型是什么

    如果是强类型语言的话,那就会给你补全代码

    那么动态类型如何实现呢?以 JS 为例,使用文档注释 即可,也就是前阵子沸沸扬扬的利用 JSDoc 代替 TS

    不仅于此,连枚举都能实现,反正 TS 有的,他应该都有,我没有详细研究

  2. 文档注释指令

    如下图所示,我想在文档注释里写上用法,但是他的格式十分丑陋,而且没有语法高亮

    于是我使用 example 指令,告诉他这是一个示例,这时就有语法高亮了

    指令还有很多,你们输入 @ 就会有提示了,比如 deprecated ,标记已弃用

    这时你使用它就会有个提示,并且划上一根线

  3. MarkDown 文档注释

    有时候,指令可能不够用,这时就可以使用 MarkDown 语法了

  4. 结合 TS

    定义类型时,写上文档注释,当你鼠标悬浮时,就能查看对应注释

    函数重载情况下,文档注释要写在类型上才行,下面这种无效

    要写在类型定义的地方才行

  5. 总结

    如果你用的是变量、函数或是 TS 定义类型,你要写注释,那就一定要写 文档注释,我跪下来求求你了 😭

代码七宗罪

让我来细数一下这坨代码的罪行,然后引出另一个主题,美化代码

下面这段,这简直是"甲级战犯",

  1. 一堆变量写了或者导入了不用,放那恶心谁呢
  2. 注释了的代码不删 (虽然可能有用,但是真丑)
  3. 都什么年代了,还在用var (坏处下面说)
  4. 用行内注释和没写区别不大,要写就写文档注释 (文档注释的优点上面解释了,不再赘述)
  5. 小学生流水账一般的代码,连个函数入口都没提供,想一句写一句
  6. 连个代码格式化都不会,多按几个回车,你的键盘不会烂掉;每个分段加个注释,你的速度慢不了多少
  7. 硬编码,所有类型用字符串直接区分,你万一要改怎么办?

语义化

我经常能看见一个文件里,写上百行,没有几个函数,没有注释,没有换行

一头扎进去,闷头写到天昏地暗的,比如下面这种

这玩意要我一行一行看?我是真的被恶心坏了

写代码要突出一个重点,看个大概,然后才能快速排查,看第三方库源码也是如此

我的习惯是写一个主入口,你叫 main | init | start 什么的都行,我只希望你能写上

然后主入口按照逻辑,给每个函数命名,这样一眼就能看出来你在干什么

如下图所示,这是我的偏好

我喜欢利用函数全局提升,把初始化函数放在文件顶部。这样每次打开一个文件,就能立刻看到大概逻辑

所以我很少用匿名函数,像上面那种全部写一坨,还都是匿名函数,我真的很难看出来谁是函数,谁是变量

这就引出一个新问题,函数的二义性

函数二义性

众所周知, JS 的类就是函数,里面有自己的 this ,可以 new 一个函数

你要知道他是函数还是类,一般是通过首字母是否大写区分

但是这仅仅是弱规范,人家爱咋写咋写,所以后来出现了匿名函数(主要还是为了解决 this)

匿名函数没有自己的 this 指向,没有 arguments,如下图

而且用 const 定义,所以也就没了函数提升,严格来说,匿名函数才是真函数

不过我觉得直接写匿名函数有点丑,而且写起来似乎繁琐一点,虽然我都是用代码片段生成的

如果用了匿名函数,那么我就没了函数提升了

所以我仅仅在以下情况使用匿名函数

  1. 作为回调函数
  2. 不需要 this
  3. 函数重载

函数重载我来说说吧,应该挺多人不知道。

比如下图,针对每一种情况,写一遍类型,这样就能更加清楚描述函数的所有参数情况

不过这样好麻烦,而且好丑啊,于是可以用接口,这时你用 function 就实现不了了

格式化

这里可能有争议性,仅仅是我个人喜欢,看着舒服

大多数写前端的,基本人手一个 Prettier 插件自动格式化,再来个 EsLint

然后也懒得看配置,默认就是 2 格缩进,回车多了会被删掉什么的

这样下来,整个文件就相当臃肿,密密麻麻的,我看着很难受

我的风格如下

  • 4 格缩进
  • 代码按照语义类型分块,写上块级文档注释
  • import 语句下面空两行,这样更加直观
  • 每一段,用独特醒目的文档注释划分
  • 定义变量优先使用 const ,并且只写一个 const
  • 函数参数过长,则一行放一个参数
  • 写行内样式以及较长字符串时( 比如函数作为字符串 ),用特殊的宽松格式书写,保持类似代码的格式化
  • if 分支语句,要多空一行,看着清爽

下面来用图演示一下,不然看着上面的描述抽象

代码按照语义类型分块,写上块级文档注释

每一段逻辑写完,用个醒目的、大块的文档注释分开。

全部执行的逻辑,放在一个 init 函数中

定义变量优先使用 const ,并且只写一个 const

比如声明变量,我喜欢这么写

按照分类,类型不同则换行,并且写上注释,仅用一个 const

来看看大众写法,可以说 99.9878987%的人都这么写,这种我一看就难受

如果你用 let ,并且用 4 格缩进,那么你就刚好对齐了,能少写一个回车

不过尽量使用 const

var 的坏处

  1. var 会变量提升,你可能拿到 undefined

  2. var 没有块级作用域,会导致变量共享

按照常识,下面代码应该输出 0,1,2,3,4

但是你里面是异步打印,于是等你打印时,i 以及加了5次了,又没有块级作用域,所以你拿到的是同一个东西

在古时候,是用立即执行函数解决的,如下图。因为函数会把变量存起来传给内部

现在用 let 就行了

所以我求求你别用 var

最后,多用换行,我跪下来求求你了 😭

相关推荐
whisperrr.1 小时前
【JavaWeb12】数据交换与异步请求:JSON与Ajax的绝妙搭配是否塑造了Web的交互革命?
前端·ajax·json
烂蜻蜓2 小时前
前端已死?什么是前端
开发语言·前端·javascript·vue.js·uni-app
Rowrey3 小时前
react+typescript,初始化与项目配置
javascript·react.js·typescript
谢尔登3 小时前
Vue 和 React 的异同点
前端·vue.js·react.js
祈澈菇凉8 小时前
Webpack的基本功能有哪些
前端·javascript·vue.js
小纯洁w8 小时前
Webpack 的 require.context 和 Vite 的 import.meta.glob 的详细介绍和使用
前端·webpack·node.js
想睡好8 小时前
css文本属性
前端·css
qianmoQ8 小时前
第三章:组件开发实战 - 第五节 - Tailwind CSS 响应式导航栏实现
前端·css
记得早睡~9 小时前
leetcode150-逆波兰表达式求值
javascript·算法·leetcode
zhoupenghui1689 小时前
golang时间相关函数总结
服务器·前端·golang·time