前端开发规范


文中带!!!表示为强制性规范,其他表示为推荐类规范
❌表示错误写法举例,✅表示正确示范写法

HTML 规范

参考资料

文档基础规范

1.声明文档版本!!!
<!-- ❌   非 HTML 5 DOCTYPE -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
</html>

<!-- ✅ -->
<!DOCTYPE html>
<html>
</html>
2.声明文档语言
<html lang="zh-CN">
  <!-- ... -->
</html>
3.设置元数据
<head>
  <!-- 字符编码 -->
  <meta charset="UTF-8">
  <!-- 关键字 -->
  <meta name="keyword" content="关键字">
  <!-- 内容描述 -->
  <meta name="description" content="描述信息...">
  <!--
    页面提供给移动设备使用时,需要设置viewport
    viewport-fit=cover:  用于兼容iPhoneX的刘海屏
  -->
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
</head>
4.设置标题!!!
<head>
  <!-- 指定title标签,有且仅有一个 -->
  <title>Document</title>
</head>

资源加载规范

1.省略type

link的type默认值为text/css;
srcipt的type默认值为text/jacascript;

<!-- ❌ -->
<link type="text/css" rel="stylesheet" href="demo.css" />
<style type="text/css">
  /* ... */
</style>
<script type="text/javascript" src="demo.js"></script>

<!-- ✅ -->
<link rel="stylesheet" href="demo.css" />
<style>
  /* ... */
</style>
<script src="demo.js"></script>
2.省略协议部分

外部资源的引用地址跟随页面协议

<!-- ❌ -->
<link rel="stylesheet" href="https://example.com" />
<script src="https://example.com"></script>

<!-- ✅ -->
<link rel="stylesheet" href="//example.com" />
<script src="//example.com"></script>
3.预加载关键资源

了解更多

<link rel="preload" href="example.css" as="style" />
<link rel="preload" href="example.js" as="script" />
4.DNS解析延迟问题处理

了解更多

<link rel="preconnect" href="//fonts.example.com/" crossorigin />
<link rel="dns-prefetch" href="//fonts.example.com/" />
5.建议head标签内引入css

css应在head中引入,因为在body中指定外部样式表和嵌入样式表可能会导致页面的重排和重绘
了解更多

<!-- ❌ -->
<body>
  <style>
    .mod-example {
      padding-left: 15px;
    }
  </style>
</body>

<!-- ✅ -->
<head>
  <style>
    .mod-example {
      padding-left: 15px;
    }
  </style>
</head>
5.建议body结束标签前引入js

除了基础库等必须要在DOM加载之前运行,其他js脚本都在靠近body结束标签前引入,以防止页面渲染的阻塞。
了解更多

<!-- ❌ -->
<head>
  <script src="example.js"></script>
</head>

<!-- ✅ -->
<body>
  ...
  <script src="example.js"></script>
</body>

编码规范

1.缩进

统一使用 2 个空格缩进,不要使用 4 个空格或 tab 缩进

<!-- ❌ -->
<!DOCTYPE html>
    <html>
    <head>
        <title>Page title</title>
    </head>
    <body>
        <img src="images/company-logo.png" alt="Company" />
        <h1 class="hello-world">Hello, world!</h1>
    </body>
</html>

<!-- ✅ -->
<!DOCTYPE html>
<html>
  <head>
    <title>Page title</title>
  </head>
  <body>
    <img src="images/company-logo.png" alt="Company" />
    <h1 class="hello-world">Hello, world!</h1>
  </body>
</html>
2.注释

1.不允许出现敏感信息,如个人隐私、公司内部信息、密码等!!!
2.单行注释,注释内容和注释符之间保留一个空格
3.多行注释,注释符单独占一行,注释内容2个空格缩进

<!-- 单行注释 -->
<!--
  多行注释
  多行注释
-->
3.标签
  1. 尽量保持标签语义化
<!-- ❌ -->
<p>标题</p>

<!-- ✅ -->
<h3>标题</h3>
  1. 标签名使用小写!!!
<!-- ❌ -->
<H1></H1>

<!-- ✅ -->
<h1></h1>
  1. 单标签不用省略结尾处的斜线,且斜线前要保留一个空格
<!-- ❌ -->
<img src="example.png" alt="example">

<!-- ✅ -->
<img src="example.png" alt="example" />
4.属性
  1. 属性值使用双引号"",不要使用单引号!!!
<!-- ❌ -->
<div class='example'></div>

<!-- ✅ -->
<div class="example"></div>
  1. Boolean属性不要声明取值

因为Boolean属性存在即表示true,不存在则表示false了解更多

<!-- ❌ -->
<input type="text" disabled="disabled" />

<!-- ✅-->
<input type="text" disabled />
  1. 自定义属性命名以data-为前缀
<!-- ❌ -->
<button list="example"></div>

<!-- ✅ -->
<button data-list="example"></button>
  1. 可访问性

了解更多

<!-- ❌ 缺少 alt 属性,无法被无障碍阅读器识别 -->
<img src="hello.jpg" />

<!-- ✅ -->
<img src="hello.jpg" alt="Welcome to visit!" />

<!-- ✅ 图片无需被无障碍阅读器识别时 -->
<img src="logo.jpg" alt="" />

<!-- ✅ 图片无需被无障碍阅读器识别时 -->
<img src="logo.jpg" role="presentation" />

模板

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <meta name="description" content="描述信息..." />
    <meta name="keyword" content="关键字a,关键字b,关键字c" />
    <meta name="viewport" content="width=device-width, minimum-scale=1.0, viewport-fit=cover" />
    <title>xx网</title>
    <link rel="stylesheet" href="example.css" />
    <style>
      /* 样式 */
    </style>
    <link rel="stylesheet" href="//example.com" />
    <script src="//example.com"></script>
  </head>
  <body>
    <!-- 单行注释 -->
    <!-- 
      多行注释...
      多行注释...
    -->
    <h3 id="container">标题</h3>
    <div class="content">
      <input data-demoData="123456" disabled />
      <img src="example.png" alt="example!" />
    </div>
    ...
    <script src="example.js"></script>
    <script>
      // ...
    </script>
  </body>
</html>

CSS规范

基本规范

  1. 必须以分号结尾 !!!
  2. 使用2个空格缩进
  3. 声明块的右大括号 } 应单独成行
  4. 单行代码不要超过100个字符
  5. 选择器和{}之间保留一个空格
  6. 属性声明单独成行(即使只有一条语句)
  7. 属性名和:之间无空格,属性值和:之间保留一个空格
  8. 尽量不要使用@import, 否则会导致浏览器处理 CSS 文件速度变慢
/* ❌ */
.header{width:100px;
    height:100px
}
/* ✅ */
.main {
  width: 100px;
  height: 100px;
}

注释规范

  1. 注释内容和注释符之间留有一个空格
/* ❌ */
.box {
  /*comment*/
  /*  comment  */
  /**
    *comment
    */
  padding: 10px;
}

/* ✅ */
.box {
  /* comment */
  /**
    * comment
    */
  padding: 10px;
}
  1. 注释行上方需留有一行空行,除非上一行是注释或块的顶部
/* ❌ */
.box {

  /* comment */
  width: 100px;
  /* comment */
  height: 100px;
}

/* ✅ */
.box {
  /* comment */
  width: 100px;

  /* comment */
  height: 100px;
}

选择器规范

  1. >+~||等组合选择器符号前后保留一个空格
/* ❌ */
.header > .leftText {
  padding: 10px;
}

/* ✅ */
.header > .leftText {
  padding: 10px;
}
  1. 使用多个选择器时,每个选择器应该单独成行;
/* ❌ */
.header, .main, .footer {
  padding: 10px;
}

/* ✅ */
.header,
.main,
.footer {
  padding: 10px;
}
  1. 组合选择器内的条目尽量不超过3个
/* ❌ */
.header > .content > .box > .left > .logo {
  padding: 10px;
}

/* ✅ */
.header > .left > .logo {
  padding: 10px;
}
  1. 尽量不使用id选择器, 尽量使用class选择器而不是标签选择器
  2. 属性选择器的值始终用双引号包裹
/* ❌ */
input[type=text] {
  width: 100px;
}

/* ✅ */
input[type="text"] {
  width: 100px;
}
  1. 选择器效率排行(只从效率看)
  • ID 选择器, 比如 #header
  • 类选择器,比如 .header
  • 标签(元素)选择器,比如 div
  • 相邻兄弟选择器,比如 h2 + p
  • 子选择器,比如 ul > li
  • 后代选择器,比如 ul a
  • 通配符选择器,比如 *
  • 属性选择器,比如 [class^="grid-"]
  • 伪类(伪元素)选择器,比如 a:hovera::before

属性规范

  1. 尽可能不要用!important
  2. 根据情况使用简写属性
/* ❌ */
.box {
  padding-top: 10px;
  padding-bottom: 10px;
  padding-left: 10px;
  padding-right: 10px;
}

/* ✅ */
.box {
  padding: 10px;
}
  1. ,分隔的属性值之后保留一个空格
/* ❌ */
.box {
  padding: 10px  20px;
}

/* ✅ */
.box {
  padding: 10px 20px;
}
  1. 使用尽可能短的十六进制值, 且使用小写字母
/* ❌ */
.box {
  color: #FFFFFF;
}

/* ✅ */
.box {
  color: #fff;
}
  1. 长度值为0时,省略掉长度单位
/* ❌ */
.box {
  padding: 0px;
}

/* ✅ */
.box {
  padding: 0;
}
  1. 保留小数点前的0,保持可读性(存在争议)
/* ❌ */
.box {
  opacity: .5;
}

/* ✅ */
.box {
  opacity: 0.5;
}
  1. 注意属性声明的顺序
  • 定位:如 position、left、right、top、bottom、z-index
  • 盒模型:如 display、float、width、height、margin、padding、border
  • 文字排版:如 font、color、line-height、text-align
  • 外观:如 background
  • 其他属性

JavaScript

编码风格

缩进!!!

使用2个空格缩进

分号!!!

必须使用分号结尾

逗号!!!

逗号分隔的多行结构,必须加上最后一个逗号,且不能使用行首逗号!!!

// ❌
const a = {
  a: 1
  , b: 2
  , c: 3
}

// ✅
const a = {
  a: 1,
  b: 2,
  c: 3,
}
{}!!!

包含类、函数、控制等由{}分隔的代码块结构

// ❌
if (a == b) 
  return 1;
else 
  return 2;

// ✅
if (a == b) {
  return 1;
} else if (a == c) {
  return 2;
} else {
  // TODO, 此处写明注释,不能出现空代码块
}
空格!!!
  1. 函数、控制语句等等左大括号前有一个空格
// ❌
function add(){
  // ...
}

// ✅
function add() {
  // ...
}
  1. 函数名和()之间无空格,
// ❌
function add (){
  // ...
}

// ✅
function add() {
  // ...
}
  1. ()[]内两侧无空格, {}内两侧有空格
// ❌
function add( 1,2 ) {
  // ...
}
const arr = [ 1, 2 ];
const obj = {a: 1, b: 2};

// ✅
function add(1, 2) {
  // ...
}
const arr = [1, 2];
const obj = { a: 1, b: 2 };
  1. 运算符(非一元)两侧有空格
// ❌
const x = 1 + y;
const a = ! x;

// ✅
const x = 1 + y;
const a = !x;
  1. 键名和键值之间有一个空格
// ❌
const obj = {
  a:1,
  b:true,
};

// ✅
const obj = {
  a: 1,
  b: true,
};

文件末尾保留一行空行;
文件最大行数1000;
单行最大字符数100;

语言特性

变量声明
  1. 尽量使用且正确使用const、let,不要使用var或者直接声明, 否则容易污染全局命名空间;
  2. 一条声明语句声明一个变量;
// ❌
const a = 1,
      b = 2;

// ✅
const a = 1;
const b = 2;
  1. 禁止连续赋值
// ❌
(function() {
  let a = b = c = 1; // b、c会变成全局变量
})();

// ✅
(function() {
  let c = 1;
  let b = c;
  let a = b;
})();
原始类型
  1. 不要使用new Number/String/Boolean, 会导致变量成为’object’类型
// ❌
const bool = new Boolean(false);
if (bool) {
  // bool是对象,所以永远是true
}

// ✅
const bool = false;
  1. 建议使用Number()parseInt()、 String()、!!进行类型转换;
  2. 使用parseInt()时总是带上基数(进制)
const str = '1';
const num = 0;
// ❌
// 转数字
const num1 = +str;
const num2 = str >> 0;
// 转布尔值
const bool1 = newBoolean(num);
// 转字符串
const str1 = new String(num);
const str2 = num + '';
const str3 = num.toString();

// ✅
// 转数字
const num11 = Number(str);
const num12 = parseInt(str, 10);
// 转布尔值
const bool11 = !!num;
// 转字符串
const str11 = String(num);
  1. 字符优先使用单引号'',需要拼接时可使用模板字符串、禁止不必要的转译字符
// ❌
const str = "hello";
const str2 = '\'this\' \i\s \"hello\"';

// ✅
const str11 = 'hello';
const str12 = `'this' is 'hello'"`;
数组
  1. 使用字面量创建数组
// ❌
const arr1 = new Array(1, 2, 3);
const arr2 = Array(1, 2, 3);

// ✅
const arr = [1, 2, 3];
const arr12 = new Array(10); // 除非设置长度
  1. 某些数组方法的回调函数中必须包含return语句,如some、map、find等需要,forEach则不需要
  2. 使用扩展运算符...处理数组,代替concat、map等。
const arr = [1, 2, 3, 4, 5];
// ❌
const arr1 = arr.map(item => item);

// ✅
const arr2 = [...arr];
  1. 使用对象解构数组
// ❌
function getPosition(div) {
  return [left, right, top, bottom];
}
const [left, _, top] = getPosition(div);

// ✅
function getPosition(div) {
  return { left, right, top, bottom };
}
const { left, top } = getPosition(div);
对象
  1. 使用字面量创建对象
// ❌
const obj1 = new Object();

// ✅
const obj2 = {};
  1. 使用对象属性和方法等简写语法,且简写的属性写一起
// ❌
const num = 1;
const str = 'hello world';
const obj1 = {
  num: num,
  add: function() {
    return num + 1;
  },
  str: str,
}

// ✅
const obj2 = {
  num,
  str,
  add() {
    return num + 1;
  }
};
  1. 属性名不要用引号, 除非包含特殊字符
// ❌
const obj1 = {
  'num': 1,
  'str': 'hello world',
  'data-1': 12,
}

// ✅
const obj2 = {
  num: 1,
  str: 'hello world',
  'data-1': 12,
}
  1. 优先使用.访问对象的属性
const obj = {
  a: 1,
}
// ❌
const a1 = obj['a'];

// ✅
const a2 = obj.a;
  1. 使用扩展运算符...处理对象
const obj = {
  a: 1,
  b: 2,
}
// ❌
const obj1 = Object.assign(obj, {c: 3});
const obj2 = Object.assign({}, original, {c: 3});

// ✅
const obj2 = {...obj, c: 3};
  1. 使用解构获取...对象属性
const obj = {
  a: 1,
  b: 2,
}
// ❌
const a = obj.a;
const b = obj.b;

// ✅
const {a, b} = obj;
函数
  1. 不要使用new Function 构造函数创建函数;
// ❌
const add = new Function('a', 'b' 'return a + b');

// ✅
const add = (a, b) => (a + b);
  1. 不要在块中使用函数声明

函数声明会有函数提升,在块外也能使用,容易产生不必要的风险。

// ❌
if (true) {
  function add1() {
    console.log('adding1');
  }
}
add(); // 能执行

// ✅
if (true) {
  const add2 = function () {
    console.log('adding2');
  };
}
add2(); // add2 is not defined
  1. 使用箭头函数代替匿名函数

代码简洁,且可以解决this指向的问题

  1. 不要使用arguments, 可以使用...args替代
// ❌
function add1(a, b) {
  const args = Array.prototype.slice.call(arguments, add.length);
  console.log(args);
}
add1(1, 2, 3, 4); // [3, 4];

// ✅
function add2(a, b, ...args) {
  console.log(args);
}
add2(1, 2, 3, 4); // [3, 4];
  1. 使用class 替代prototype
// ❌
function Person() {
  this.age = 20;
}
Person.prototype.add = function() {
  this.age += 1;
}

// ✅
class Person {
  constructor() {
    this.age = 20;
  }
  add() {
    this.age += 1;
  }
}
  1. 使用extends进行类的继承
// ✅
class ChinesePerson extends Person {
  // ...
}
模块
  1. 使用ES6 modules, 除非Node.js运行环境
// ❌
const Demo = require('demo');
module.exports = Demo;

// ✅
import Demo from 'demo';
export default Demo;
  1. 不要使用多个import引入同一个模块
// ❌
import {a} from 'demo';
import Demo from 'demo';
import {b} from 'demo';

// ✅
import Demo, {a, b} from 'demo';
  1. import放到模块最上方
// ❌
import foo from 'foo';
foo.init();
import bar from 'bar';
bar.init();

// ✅
import foo from 'foo';
import bar from 'bar';
foo.init();
bar.init();
  1. 导入排序规则
  • 先第三方模块、 再工程内模块
  • 先绝对路径, 再相对路径
  1. 再模块导入之后保留一个空行
// ❌
import add from 'add';
add();

// ✅
import del from 'del';

del();
操作符
  1. 使用严格相等运算符
const a = '1';
const b = 2;
// ❌
if (a == b) {
  // ...
}

// ✅
if (Number(a) === b) {
  // ...
}
  1. 除了在for循环条件中,其他情况不要使用一元自增自减运算符
const a = 1;
// ❌
a ++;

// ✅
a += 1;
  1. 避免嵌套的三元运算符
// ❌
const z = s === 'a' ? 1: s === 'b'? 2 : 3;

// ✅
const x = s === 'b' ? 2 : 3;
const y = s === 'a' ? 1 : x;
  1. 混合使用操作符时,使用小括号()包裹
// ❌ 容易误以为执行顺序是(a || b) && c
if (a || b ** c) {
  //...
}

// ✅
if (a || (b && c)) {
  // ...
}
控制语句
  1. switch 至少要包含3个条件分支,且必须有default分支
  2. 嵌套层级不要超过四层,如if、for等
  3. for-in循环中要对key进行验证
// ❌
for (const key in obj) {
  console.log(key, obj[key]);
}

//  ✅
for (const key in obj) {
  if (Object.prototype.hasOwnProperty.call(obj, key)) {
    console.log(key, obj[key]);
  }
}
注释
  1. 注释内容和注释符之间保留一个空格
  2. 单行注释使用 //, 单独占一行,写在被注释对象上方
// ❌
const a = 1; // this is a
const b = 2; // this is b

// ✅
// this is a
const a = 1;

// this is b
const b = 2; 
  1. 多行注释使用 /** ... */
// ❌
// this is What about the following
// this is element
function add2() {
  // ...
}

// ✅
/**
 * @description xxx
  * @param xxx
  */
function add2() {
  // ...
}
  1. 函数注释使用jsdoc规范

文档类注释,如函数、类、文件、事件等, 推荐使用jsdoc规范 详情

/**
 * 加法
 * @param {number} a 数字a
 * @param {number} b 数字b
 */
function add(a, b) {
  return a + b;
}
  1. 推荐使用文件表头注释

推荐vscode插件 vscode-fileheader
可以显示作者、创建日期、描述等(可以配置自定义显示内容)

/*
  * @Author: Tom
  * @Date: 2023-08-24 11:53:29
  * @Last Modified by: Tom
  * @Last Modified time: 2023-08-24 11:53:29
  * @Description: 封装的函数
  */
  1. 合理使用特殊注释标记
// TODO 表示待做的功能
// FIXME 表示待处理的问题
// ...
其他
  1. 禁止使用eval、debugger、alert、console等(生产环境);
  2. 禁止对原生对象或只读的全局对象进行赋值,如window = {}; undefined = 1等
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

[chao]

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值