🎮前端代码规范 —— JS
00 分钟
2022-8-22
2022-9-15
type
status
date
slug
summary
tags
category
icon
password
Edited
Sep 15, 2022 01:16 PM
Created
Aug 22, 2022 08:07 AM

语言规范

notion image

类型

  • 原始类型: 存取原始类型直接作用于值本身
    • 布尔类型
    • Null 类型
    • Undefined 类型
    • 数字类型
    • BigInt 类型
    • 字符串类型
    • 符号类型 Symbol
  • 复杂类型: 访问复杂类型作用于值的引用
    • object
    • array
    • function

引用

  • 请记得 const 和 let 都是块级作用域,var 是函数级作用域
  • 对所有引用都使用 const,不要使用 var
  • 如果引用是可变动的,使用 let代替 var

对象

  • 使用字面量值创建对象
  • 别使用保留字作为对象的键值
  • 当使用动态属性名创建对象时,请使用对象计算属性名来进行创建
  • 使用对象方法的简写方式
  • 请使用对象属性值的简写方式
  • 将简写的对象属性分组后统一放到对象声明的开头
  • 只对非法标识符的属性使用引号
  • 不要直接使用 Object.prototype的方法, 例如 hasOwnPropertypropertyIsEnumerable 和 isPrototypeOf方法
  • 优先使用对象展开运算符 ... 来做对象浅拷贝而不是使用 Object.assign,使用对象剩余操作符来获得一个包含确定的剩余属性的新对象

数组

  • 请使用字面量值创建数组
  • 向数组中添加元素时,请使用 push 方法
  • 使用展开运算符 ... 复制数组
  • 把一个可迭代的对象转换为数组时,使用展开运算符 ... 而不是 Array.from
  • 使用 Array.from 来将一个类数组对象转换为数组
  • 遍历迭代器进行映射时使用 Array.from 代替扩展运算符 ..., 因为这可以避免创建中间数组
  • 使用数组的 map等方法时,请使用 return声明,如果是单一声明语句的情况,可省略 return
  • 如果一个数组有多行则要在数组的开括号后和闭括号前使用新行

解构赋值

  • 当需要使用对象的多个属性时,请使用解构赋值
  • 当需要使用数组的多个值时,请同样使用解构赋值
  • 函数需要回传多个值时,请使用对象的解构,而不是数组的解构

字符串

  • 字符串统一使用单引号的形式 ''
  • 字符串太长的时候,请不要使用字符串连接符换行 \,而是使用 +
  • 程序化生成字符串时,请使用模板字符串
  • 不要对字符串使用eval(),会导致太多漏洞
  • 不要在字符串中使用不必要的转义字符

函数

  • 不要使用Function构造函数创建函数
  • 在函数签名中使用空格
  • 使用具名函数表达式而非函数声明
  • 用圆括号包裹自执行匿名函数
  • 不要在非函数代码块(ifwhile等)中声明函数
  • 不要将参数命名为 arguments,会导致该参数的优先级高于每个函数作用域内原先存在的 arguments 对象
  • 不要使用 arguments,使用 剩余运算符 ...
  • 使用参数默认值语法而不是修改函数参数
  • 避免参数默认值的副作用
  • 将参数默认值放在最后
  • 不要更改参数
  • 不要给参数重新赋值
  • 调用可变参数函数时建议使用展开运算符 ...

箭头函数

  • 当你必须使用函数表达式(传递匿名函数)时,使用箭头函数标记
  • 如果函数体只包含一条没有副作用的返回表达式的语句,可以省略花括号并使用隐式的 return , 否则保留花括号并使用 return语句
  • 一旦表达式跨多行,使用圆括号包裹以便更好阅读
  • 函数如果只接收一个参数并且没使用用花括号,则省略圆括号,否则为了清晰明确则使用圆括号包裹参数,注意:总是使用圆括号也是可以接受的

类&构造函数

  • 使用 class,避免直接操作 prototype
  • 使用 extends 来实现继承
  • 如果未声明构造函数,则类会有一个默认的构造函数,没必要用空的构造函数或者将其委托给父类
  • 避免类成员重复

模块

  • 使用标准的 ES6 模块语法 import 和 export
  • 不要使用 import的通配符 *,这样可以确保你只有一个默认的 export
  • 同个文件每个模块只允许 import一次,有多个 import请书写在一起
  • 将所有 import语句放在文件最前方
  • 多行导入应该像多行数组和对象文字一样缩进
  • 在模块 import声明中禁止使用 Webpack的 loader语法
  • 在模块导入之后保留一个空行
  • 当模块内只有一个 export 时,使用 default export

迭代器

  • 不要使用 iterators,建议使用 JS 更高优先级的函数代替 for-in 或 for-of 循环,除非迫不得已
  • 现阶段请不要使用生成器 generator

对象属性

  • 使用 . 来访问对象属性
  • 当访问的属性是变量时使用 []

变量声明

  • 声明变量时,请使用 constlet关键字,如果没有写关键字,变量就会暴露在全局上下文中,这样很可能会和现有变量冲突,另外,也很难明确该变量的作用域是什么。这里推荐使用 const来声明变量,我们需要避免全局命名空间的污染
  • 将所有的 const和 let分组
  • 变量不要进行链式赋值
  • 不允许出现未被使用的变量

Hoisting

  • var存在变量提升的情况,即 var声明会被提升至该作用域的顶部,但是他们的赋值并不会。而 const和 let并不存在这种情况
  • 匿名函数的变量名会提升,但函数内容不会
  • 命名的函数表达式的变量名会被提升,但函数名和函数函数内容并不会

比较运算符&相等

  • 使用 === 和 !== 而非 == 和 !=
  • 条件声明例如 if 会用 ToBoolean 这个抽象方法将表达式转成布尔值并遵循如下规则
    • Objects 等于 true
    • Undefined 等于 false
    • Null 等于 false
    • Booleans 等于 布尔值
    • Numbers 在 +00, 或者 NaN 的情况下等于 false, 其他情况是 true
    • Strings 为 '' 时等于 false, 否则是 true

操作符

  • 【强制】不要使用一元自增自减运算符
    • 不要使用一元自增自减运算符(++ 和 --),除非在 for 循环条件中。
      ++ 和 -- 会带来值�是否会提前变化带来的理解成本,也可能因为自动添加分号机制导致一些错误,因此我们推荐使用 num += 1 来代替 num++。但出于习惯,在 for 循环的条件中依然可以使用自增自减运算符
  • 避免嵌套的三元表达式
  • 混合使用多种操作符时,用小括号包裹分组

分号

我们遵循 Standard的规范,不使用分号

eval()

由于 eval 方法比较 evil,所以我们约定禁止使用该方法

with() {}

由于 with 方法会产生神奇的作用域,所以我们也是禁止使用该方法的

修改内置对象的原型

不要修改内置对象,如 Object 和 Array
 

代码规范

单行代码块

在单行代码块中使用空格

大括号风格

在编程过程中,大括号风格与缩进风格紧密联系,用来描述大括号相对代码块位置的方法有很多。在 JavaScript 中,主要有三种风格,如下
  • One True Brace Style
约定使用 One True Brace Style风格

变量命名

约定使用驼峰式命名(constiableName)

拖尾逗号

在 ECMAScript5 里面,对象字面量中的拖尾逗号是合法的,但在 IE8(非 IE8 文档模式)下,当出现拖尾逗号,则会抛出错误
拖尾逗号的好处是,简化了对象和数组添加或删除元素,我们只需要修改新增的行即可,并不会增加差异化的代码行数
因为拖尾逗号有好也有不好,所以团队约定允许在最后一个元素或属性与闭括号 ]或 }在不同行时,可以(但不要求)使用拖尾逗号。当在同一行时,禁止使用拖尾逗号
【强制】对于逗号分隔的多行结构,始终加上最后一个逗号

逗号空格

逗号前后的空格可以提高代码的可读性,团队约定在逗号后面使用空格,逗号前面不加空格。

逗号风格

标准风格,逗号放置在当前行的末尾

计算属性的空格

团队约定在对象的计算属性内,禁止使用空格

拖尾换行

在非空文件中,存在拖尾换行是一个常见的 UNIX风格,它的好处是可以方便在串联和追加文件时不会打断 Shell的提示。在日常的项目中,保留拖尾换行的好处是,可以减少版本控制时的代码冲突
vscode中添加:

函数调用

为了避免语法错误,团队约定在函数调用时,禁止使用空格

缩进

姑且约定使用 空格来缩进,而且缩进使用两个空格
通过配置 .editorconfig,将 Tab自动转换为空格

对象字面量的键值缩进

团队约定对象字面量的键和值之间不能存在空格,且要求对象字面量的冒号和值之间存在一个空格

构造函数首字母大写

在 JavaScript 中 new操作符用来创建某个特定类型的对象的一个实例,该类型的对象是由一个构造函数表示的。由于构造函数只是常规函数,唯一区别是使用 new来调用。所以我们团队约定构造函数的首字母要大小,以此来区分构造函数和普通函数

构造函数的参数

在 JavaScript 中,通过 new 调用构造函数时,如果不带参数,可以省略后面的圆括号。但这样会造成与整体的代码风格不一致,所以团队约定使用圆括号

链式调用

链式调用如果放在同一行,往往会造成代码的可读性差,但有些时候,短的链式调用并不会影响美观。所以本规范约定一行最多只能有四个链式调用,超过就要求换行

空行

空白行对于分离代码逻辑有帮助,但过多的空行会占据屏幕的空间,影响可读性。团队约定最大连续空行数为 2
【强制】块�的开始和结束不能是空行
在块末和新语句间插入一个空行

链式赋值

链式赋值容易造成代码的可读性差,所以团队约定禁止使用链式赋值

变量声明

JavaScript 允许在一个声明中,声明多个变量。团队约定在声明变量时,一个声明只能有一个变量

分号

JavaScript 在所有类 C 语言中是比较独特的,它不需要在每个语句的末尾有分号。在很多情况下,JavaScript 引擎可以确定一个分号应该在什么位置然后自动添加它。此特征被称为 自动分号插入 (ASI),被认为是 JavaScript 中较为有争议的特征
本规范推荐不使用分号

代码块空格

一致性是任何风格指南的重要组成部分。虽然在哪里放置块的开括号纯属个人偏好,但在整个项目中应该保持一致。不一致的风格将会分散读者阅读代码的注意力
约定代码块前要添加空格

函数声明的空格

当格式化一个函数,函数名或 function 关键字与左括号之间允许有空白。命名函数要求函数名和 function 关键字之间有空格,但是匿名函数要求不加空格

操作符的空格

团队约定操作符前后都需要添加空格

最大字符数和最大行数

  • 【推荐】单行最大字符数:120
    • 我们推荐单行代码最多不要超过 100 个字符,除了以下两种情况:
    • 字符串和模板字符串
    • 正则表达式
  • 文件最大行数:1000
  • 函数最大行数:80
 

框架规范

命名规范

  • 组件文件名
    • 如果是组件文件,则使用 PascalCase,如 MyComponent.js
      如果组件是一个目录,则组件主入口命名为 index,如 index.js
  • 引用命名
    • React 组件使用 PascalCase,组件实例使用 CamelCase
  • 组件命名
  • 组件属性名
    • 使用小驼峰式命名法来定义属性的名称

空格

  • 自闭合的标签前要加一个空格
  • 不要在花括号里边加空格

属性

  • 属性名使用 CamelCase
  • 当属性值为true时可以省略
  • 避免使用数组的索引作为 key 属性值, 建议使用稳定的ID
  • 为所有的非必需属性定义使用 defaultProps 明确的默认值

标签

  • 没有子元素的标签请自闭合
  • 如果组件包含多行属性,在新的一行闭合标签

方法

  • 使用箭头函数包裹本地变量
  • 类组件的内部方法不要使用下划线前缀
 

类型

类型检测

[建议] 类型检测优先使用 typeof。对象类型检测使用 instanceofnull 或 undefined 的检测使用 == null

类型转换

[建议] 转换成 string 时,使用 + ''
[建议] 转换成 number 时,通常使用 +
[建议] string 转换成 number,要转换的字符串结尾包含非数字并期望忽略时,使用 parseInt
[强制] 使用 parseInt 时,必须指定进制。
[建议] 转换成 boolean 时,使用 !!
[建议] number 去除小数点,使用 Math.floor / Math.round / Math.ceil,不使用 parseInt
 

注释

文档类注释使用 jsdoc 规范
文档类注释,如函数、类、文件、事件等,推荐使用 jsdoc规范或类 jsdoc 的规范
无用的代码注释应被即时删除

文件注释

[强制] 文件顶部必须包含文件注释,用 @file 标识文件说明

命名空间注释

[建议] 命名空间使用 @namespace 标识

类注释

[建议] 使用 @class 标记类或构造函数。
[建议] 使用 @extends 标记类的继承信息。
[强制] 使用包装方式扩展类成员时, 必须通过 @lends 进行重新指向。
[强制] 类的属性或方法等成员信息不是 public 的,应使用 @protected 或 @private 标识可访问性。

函数/方法注释

[强制] 函数/方法注释必须包含函数说明,有参数和返回值时必须使用注释标识
当 return关键字仅作退出函数/方法使用时,无须对返回值作注释标识
[强制] 参数和返回值注释必须包含类型信息,且不允许省略参数的说明
[建议] 当函数是内部函数,外部不可访问时,可以使用 @inner 标识
[强制] 对 Object 中各项的描述, 必须使用 @param 标识
[建议] 重写父类方法时, 应当添加 @override 标识。如果重写的形参个数、类型、顺序和返回值类型均未发生变化,可省略 @param@return,仅用 @override 标识,否则仍应作完整注释

事件注释

[强制] 必须使用 @event 标识事件,事件参数的标识与方法描述的参数标识相同

常量注释

[强制] 常量必须使用 @const 标记,并包含说明和类型信息

复杂类型注释

[建议] 对于类型未定义的复杂结构的注释,可以使用 @typedef 标识来定义
 
 

参考链接:
  1. 概述 | Aotu.io - 前端代码规范
  1. spec/javascript-style-guide.md at master · ecomfe/spec (github.com)
 
上一篇
前端代码规范 —— 图片
下一篇
前端代码规范 —— CSS

评论
Loading...