前端设计与编码规范

V1.2 @Suming Lv


[TOC]目录

0.0 总体原则

0.1 核心思想

表现、内容和行为的分离。
标记应该是结构良好、语义正确 以及 普遍合法。
渐进增强,提高用户体验。

0.2 基本原则

代码一致性:
通过保持代码风格和传统的一致性,我们可以减少遗留系统维护的负担,并降低未来系统崩溃的风险。
最佳实践:
通过遵照最佳实践,我们能确保优化的页面加载、性能以及可维护的代码。

0.3 适用原则

本规范中条目如无特殊说明的,需参照执行。其中:
*为建议
**为必须

1.0 命名规则

1.1 项目命名

  • 全部采用小写方式,以中划线分隔。
  • 避免单字母命名。命名应具备描述性。

例:my-project-name

1.2 目录命名

参照项目命名规则;

有复数结构时,要采用复数命名法。

例:scripts, styles, images, data-models

1.3 文件命名

参照项目命名规则。

例:
HTML文件命名:error-report.html
JS文件命名:account-model.js
CSS, LESS文件命名:retina-sprites.less

1.4 HTML命名

参照项目命名规则。

1.5 JS命名

1.5.1 函数命名

  • 使用小驼峰式命名对象、函数和实例。
  • 使用下划线 _ 开头命名私有属性。

1) 获取单个对象的方法用 get 做前缀。
2) 获取多个对象的方法用 list 做前缀。
3) 获取统计值的方法用 count 做前缀。
4) 插入的方法用 save(推荐)或 insert 做前缀。
5) 删除的方法用 remove(推荐)或 delete 做前缀。
6) 修改的方法用 update 做前缀。

1.5.2 分页命名

1) 传参值:current(当前页,默认1)、size(分页数,默认10)
2) 响应值:total(总页数,默认0)

1.5.3 其他

说明:任何类、方法、参数、变量,严控访问范围。过宽泛的访问范围,不利于模块解耦。

1.6 CSS, LESS命名

参照项目命名规则。

2.0 HTML

2.1 语法

用四个空格来代替制表符(tab)。
嵌套元素应当缩进一次(即四个空格)。
对于属性的定义,确保全部使用双引号,而不要使用单引号。
不要在自闭合(self-closing)元素的尾部添加斜线。
IMG元素加alt注释。
为超过12行的元素块或关键逻辑添加注释,全部采用如下格式。

  <!-- comment Begin -->                       
	...
  <!-- comment Begin -->
复制代码

HTML里插入JS时,前后需要增加空格
段落分隔符要使用实际对应的<p>元素,而不是用多个<br>标签。
在合适的条件下,充分利用<dl>(定义列表)和<blockquote>标签。
列表中的条目必须总是放置于<ul><ol><dl>中,永远不要用一组 <div><p>来表示。
给每个表单里的字段加上<label>标签,其中的 for 属性必须和对应的输入字段对应,这样用户就可以点击标签。同理,给标签也加上 cursor:pointer; 。
不用使用输入字段中的 size 属性。该属性是和输入字段里文本的 font-size 相关的。应该使用CSS宽度。
在某些闭合的</div>标签旁边加上一段html注释,说明这里闭合的是什么元素。这在有大量嵌套和缩进的情况下会很有用。
不要把表格用于页面布局。
在合适的条件下,利用 microformats 和/或者 Microdata ,具体说是 hCard 和 adr。
在合适的条件下,利用<thead><tbody><th>标签 (以及Scope属性)。
避免使用过时的标签,如:<b><u><i>,而用<strong><em>等代替。
使用data-xxx来添加自定义数据,如:<input data-xxx="yyy"/>
其他字符实体请参照:字符实体

2.2 HTML5 Doctype

HTML5下默认使用:<!DOCTYPE HTML>

2.3 lang属性

html标签应加上lang属性。

2.4 meta

meta的使用需要根据具体需求按需选择,具体可参照:cool-head
Demo:

<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="favicon.ico">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
复制代码

2.5 IE兼容模式

<meta>标签可以指定页面应该用什么版本的IE来渲染;

2.6 引入 CSS 和 JavaScript 文件

根据 HTML5 规范,在引入 CSS 和 JavaScript 文件时一般不需要指定 type 属性,因为 text/css 和 text/javascript 分别是它们的默认值。

2.7 属性顺序*

属性应该按照特定的顺序出现以保证易读性;

class  
id  
name  
data-*  
src, for, type, href, value , max-length, max, min, pattern  
placeholder, title, alt  
aria-*, role  
required, readonly, disabled  
复制代码

[//]: # class是为高可复用组件设计的,所以应处在第一位;
[//]: # id更加具体且应该尽量少使用,所以将它放在第二位。

2.8 boolean属性

boolean属性指不需要声明取值的属性,XHTML需要每个属性声明取值,但是HTML5并不需要;

<input type="text" disabled>
<input type="checkbox" value="1" checked>
<select>
    <option value="1" selected>1</option>
</select>
复制代码

2.9 JS生成标签

在JS文件中生成标签让内容变得更难查找,更难编辑,性能更差。应该尽量避免这种情况的出现。

2.10 减少标签数量

在编写HTML代码时,需要尽量避免多余的父节点;
很多时候,需要通过迭代和重构来使HTML变得更少。

2.11 实用高于完美

尽量遵循HTML标准和语义,但是不应该以浪费实用性作为代价;
任何时候都要用尽量小的复杂度和尽量少的标签来解决问题。

3.0 CSS, SCSS, LESS

使用 normalize.css 让渲染效果在不同浏览器中更一致

3.1 缩进

使用4个空格。

3.2 分号

每个属性声明末尾都要加分号。

3.3 空格

以下几种情况不需要空格:

属性名后 多个规则的分隔符','前
!important '!'后
属性值中'('后和')'前
行末不要有多余的空格
以下几种情况需要空格:

属性值前 选择器'>', '+', '~'前后
'{'前
!important '!'前
@else 前后
属性值中的','后
注释'/'后和'/'前

3.4 空行

以下几种情况需要空行:

文件最后保留一个空行
'}'后最好跟一个空行,包括less中嵌套的规则
属性之间需要适当的空行,具体见属性声明顺序

3.5 换行

以下几种情况不需要换行:
'{'前

以下几种情况需要换行:
'{'后和'}'前
每个属性独占一行
多个规则的分隔符','后

3.6 注释

注释统一用'/* */'(less或scss中也不要用'//')。
缩进与下一行代码保持一致;
可位于一个代码行的末尾,与代码间隔一个空格。

3.7 引号

最外层统一使用双引号;
url的内容要用引号;
属性选择器中的属性值需要引号。

3.8 命名

类名使用小写字母,以中划线分隔
id采用驼峰式命名
less或scss中的变量、函数、混合、placeholder采用驼峰式命名

3.9 属性声明顺序*

相关的属性声明按以下顺序做分组处理,组之间需要有一个空行。
布局定位属性–>自身属性–>文本属性–>其他属性

// 例:
.declaration-order {
  display: block;
  float: right;

  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 100;

  border: 1px solid #e5e5e5;
  border-radius: 3px;
  width: 100px;
  height: 100px;

  font: normal 13px "Helvetica Neue", sans-serif;
  line-height: 1.5;
  text-align: center;

  color: #333;
  background-color: #f5f5f5;

  opacity: 1;
}


// 下面是推荐的属性的顺序
[
  [
      "display",
      "visibility",
      "float",
      "clear",
      "overflow",
      "overflow-x",
      "overflow-y",
      "clip",
      "zoom"
  ],
  [
      "table-layout",
      "empty-cells",
      "caption-side",
      "border-spacing",
      "border-collapse",
      "list-style",
      "list-style-position",
      "list-style-type",
      "list-style-image"
  ],
  [
      "-webkit-box-orient",
      "-webkit-box-direction",
      "-webkit-box-decoration-break",
      "-webkit-box-pack",
      "-webkit-box-align",
      "-webkit-box-flex"
  ],
  [
      "position",
      "top",
      "right",
      "bottom",
      "left",
      "z-index"
  ],
  [
      "margin",
      "margin-top",
      "margin-right",
      "margin-bottom",
      "margin-left",
      "-webkit-box-sizing",
      "-moz-box-sizing",
      "box-sizing",
      "border",
      "border-width",
      "border-style",
      "border-color",
      "border-top",
      "border-top-width",
      "border-top-style",
      "border-top-color",
      "border-right",
      "border-right-width",
      "border-right-style",
      "border-right-color",
      "border-bottom",
      "border-bottom-width",
      "border-bottom-style",
      "border-bottom-color",
      "border-left",
      "border-left-width",
      "border-left-style",
      "border-left-color",
      "-webkit-border-radius",
      "-moz-border-radius",
      "border-radius",
      "-webkit-border-top-left-radius",
      "-moz-border-radius-topleft",
      "border-top-left-radius",
      "-webkit-border-top-right-radius",
      "-moz-border-radius-topright",
      "border-top-right-radius",
      "-webkit-border-bottom-right-radius",
      "-moz-border-radius-bottomright",
      "border-bottom-right-radius",
      "-webkit-border-bottom-left-radius",
      "-moz-border-radius-bottomleft",
      "border-bottom-left-radius",
      "-webkit-border-image",
      "-moz-border-image",
      "-o-border-image",
      "border-image",
      "-webkit-border-image-source",
      "-moz-border-image-source",
      "-o-border-image-source",
      "border-image-source",
      "-webkit-border-image-slice",
      "-moz-border-image-slice",
      "-o-border-image-slice",
      "border-image-slice",
      "-webkit-border-image-width",
      "-moz-border-image-width",
      "-o-border-image-width",
      "border-image-width",
      "-webkit-border-image-outset",
      "-moz-border-image-outset",
      "-o-border-image-outset",
      "border-image-outset",
      "-webkit-border-image-repeat",
      "-moz-border-image-repeat",
      "-o-border-image-repeat",
      "border-image-repeat",
      "padding",
      "padding-top",
      "padding-right",
      "padding-bottom",
      "padding-left",
      "width",
      "min-width",
      "max-width",
      "height",
      "min-height",
      "max-height"
  ],
  [
      "font",
      "font-family",
      "font-size",
      "font-weight",
      "font-style",
      "font-variant",
      "font-size-adjust",
      "font-stretch",
      "font-effect",
      "font-emphasize",
      "font-emphasize-position",
      "font-emphasize-style",
      "font-smooth",
      "line-height",
      "text-align",
      "-webkit-text-align-last",
      "-moz-text-align-last",
      "-ms-text-align-last",
      "text-align-last",
      "vertical-align",
      "white-space",
      "text-decoration",
      "text-emphasis",
      "text-emphasis-color",
      "text-emphasis-style",
      "text-emphasis-position",
      "text-indent",
      "-ms-text-justify",
      "text-justify",
      "letter-spacing",
      "word-spacing",
      "-ms-writing-mode",
      "text-outline",
      "text-transform",
      "text-wrap",
      "-ms-text-overflow",
      "text-overflow",
      "text-overflow-ellipsis",
      "text-overflow-mode",
      "-ms-word-wrap",
      "word-wrap",
      "-ms-word-break",
      "word-break"
  ],
  [
      "color",
      "background",
      "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader",
      "background-color",
      "background-image",
      "background-repeat",
      "background-attachment",
      "background-position",
      "-ms-background-position-x",
      "background-position-x",
      "-ms-background-position-y",
      "background-position-y",
      "-webkit-background-clip",
      "-moz-background-clip",
      "background-clip",
      "background-origin",
      "-webkit-background-size",
      "-moz-background-size",
      "-o-background-size",
      "background-size"
  ],
  [
      "outline",
      "outline-width",
      "outline-style",
      "outline-color",
      "outline-offset",
      "opacity",
      "filter:progid:DXImageTransform.Microsoft.Alpha(Opacity",
      "-ms-filter:\\'progid:DXImageTransform.Microsoft.Alpha",
      "-ms-interpolation-mode",
      "-webkit-box-shadow",
      "-moz-box-shadow",
      "box-shadow",
      "filter:progid:DXImageTransform.Microsoft.gradient",
      "-ms-filter:\\'progid:DXImageTransform.Microsoft.gradient",
      "text-shadow"
  ],
  [
      "-webkit-transition",
      "-moz-transition",
      "-ms-transition",
      "-o-transition",
      "transition",
      "-webkit-transition-delay",
      "-moz-transition-delay",
      "-ms-transition-delay",
      "-o-transition-delay",
      "transition-delay",
      "-webkit-transition-timing-function",
      "-moz-transition-timing-function",
      "-ms-transition-timing-function",
      "-o-transition-timing-function",
      "transition-timing-function",
      "-webkit-transition-duration",
      "-moz-transition-duration",
      "-ms-transition-duration",
      "-o-transition-duration",
      "transition-duration",
      "-webkit-transition-property",
      "-moz-transition-property",
      "-ms-transition-property",
      "-o-transition-property",
      "transition-property",
      "-webkit-transform",
      "-moz-transform",
      "-ms-transform",
      "-o-transform",
      "transform",
      "-webkit-transform-origin",
      "-moz-transform-origin",
      "-ms-transform-origin",
      "-o-transform-origin",
      "transform-origin",
      "-webkit-animation",
      "-moz-animation",
      "-ms-animation",
      "-o-animation",
      "animation",
      "-webkit-animation-name",
      "-moz-animation-name",
      "-ms-animation-name",
      "-o-animation-name",
      "animation-name",
      "-webkit-animation-duration",
      "-moz-animation-duration",
      "-ms-animation-duration",
      "-o-animation-duration",
      "animation-duration",
      "-webkit-animation-play-state",
      "-moz-animation-play-state",
      "-ms-animation-play-state",
      "-o-animation-play-state",
      "animation-play-state",
      "-webkit-animation-timing-function",
      "-moz-animation-timing-function",
      "-ms-animation-timing-function",
      "-o-animation-timing-function",
      "animation-timing-function",
      "-webkit-animation-delay",
      "-moz-animation-delay",
      "-ms-animation-delay",
      "-o-animation-delay",
      "animation-delay",
      "-webkit-animation-iteration-count",
      "-moz-animation-iteration-count",
      "-ms-animation-iteration-count",
      "-o-animation-iteration-count",
      "animation-iteration-count",
      "-webkit-animation-direction",
      "-moz-animation-direction",
      "-ms-animation-direction",
      "-o-animation-direction",
      "animation-direction"
  ],
  [
      "content",
      "quotes",
      "counter-reset",
      "counter-increment",
      "resize",
      "cursor",
      "-webkit-user-select",
      "-moz-user-select",
      "-ms-user-select",
      "user-select",
      "nav-index",
      "nav-up",
      "nav-right",
      "nav-down",
      "nav-left",
      "-moz-tab-size",
      "-o-tab-size",
      "tab-size",
      "-webkit-hyphens",
      "-moz-hyphens",
      "hyphens",
      "pointer-events"
  ]
]
复制代码

3.10 颜色

颜色16进制用小写字母;
颜色16进制尽量用简写。

3.11 属性简写

属性简写需要你非常清楚属性值的正确顺序,而且在大多数情况下并不需要设置属性简写中包含的所有值,所以建议尽量分开声明会更加清晰; margin 和 padding 相反,需要使用简写;
常见的属性简写包括:
font
background
transition
animation

3.12 媒体查询

尽量将媒体查询的规则靠近与他们相关的规则,不要将他们一起放到一个独立的样式文件中,或者丢在文档的最底部,这样做只会让大家以后更容易忘记他们。

.element {
    ...
}

.element-avatar{
    ...
}

@media (min-width: 480px) {
  .element {
      ...
  }

  .element-avatar {
      ...
  }
}
复制代码

3.13 LESS或SCSS相关

提交的代码中不要有 @debug;

声明顺序:

@extend
不包含 @content 的 @include
包含 @content 的 @include
自身属性
嵌套规则
@import 引入的文件不需要开头的'_'和结尾的'.scss';

嵌套最多不能超过5层;

@extend 中使用placeholder选择器;

去掉不必要的父级引用符号'&'。

3.14 杂项

不允许有空的规则;

元素选择器用小写字母;

去掉小数点前面的0;

去掉数字中不必要的小数点和末尾的0;

属性值'0'后面不要加单位;

同个属性不同前缀的写法需要在垂直方向保持对齐,具体参照右边的写法;

无前缀的标准属性应该写在有前缀的属性后面;

不要在同个规则里出现重复的属性,如果重复的属性是连续的则没关系;

不要在一个文件里出现两个相同的规则;

用 border: 0; 代替 border: none;;

选择器不要超过4层(在scss中如果超过4层应该考虑用嵌套的方式来写);

发布的代码中不要有 @import;

尽量少用'*'选择器。

4.0 JavaScript

4.1 缩进

  • 使用4个空格
  • 不要混用tab和space;
  • 不要在一处使用多个tab或space;

4.2 单行长度

  • 不要超过80,使用字符串连接号连接(word wrap可不考虑单行长度)。
  • 程序化生成字符串时,使用模板字符串替代字符串连接。
// good
function sayHi(name){
    return `How are you ${name}?`
}
复制代码

4.3 分号

每行逻辑后面需要以分号结尾

4.4 空格

以下几种情况不需要空格:

对象的属性名后
前缀一元运算符后
后缀一元运算符前
函数调用括号前
无论是函数声明还是函数表达式,'('前不要空格
数组的'['后和']'前
对象的'{'后和'}'前
运算符'('后和')'前

以下几种情况需要空格:

二元运算符前后
三元运算符'?:'前后
代码块'{'前
下列关键字前:else, while, catch, finally
下列关键字后:if, else, for, while, do, switch, case, try, catch, finally, with, return, typeof
单行注释'//'后(若单行注释和代码同行,则'//'前也需要),多行注释'*'后
对象的属性值前
for循环,分号后留有一个空格,前置条件如果有多个,逗号后留一个空格
无论是函数声明还是函数表达式,'{'前一定要有空格
函数的参数之间

// not good
var a = {
  b :1
}

// good
var a = {
  b: 1
}

// not good
++ x
y ++
z = x?1:2

// good
++x
y++
z = x ? 1 : 2

// not good
var a = [ 1, 2 ]

// good
var a = [1, 2]

// not good
var a = ( 1+2 )*3

// good
var a = (1 + 2) * 3

// no space before '(', one space before '{', one space between function parameters
var doSomething = function(a, b, c) {
    // do something
}

// no space before '('
doSomething(item)

// not good
for(i=0;i<6;i++){
  x++
}

// good
for (i = 0; i < 6; i++) {
  x++
}
复制代码

4.5 空行

以下几种情况需要空行:

变量声明后(当变量声明在代码块的最后一行时,则无需空行)
注释前(当注释在代码块的第一行时,则无需空行)
代码块后(在函数调用、数组、对象中则无需空行)
文件最后保留一个空行

4.6 换行

换行的地方,行末必须有','或者运算符;

以下几种情况不需要换行:

下列关键字后:else, catch, finally
代码块'{'前

以下几种情况需要换行:

代码块'{'后和'}'前
变量赋值后

// not good
var a = {
    b: 1
    , c: 2
};

x = y
    ? 1 : 2;

// good
var a = {
    b: 1,
    c: 2
};

x = y ? 1 : 2;
x = y ?
    1 : 2;

// no need line break with 'else', 'catch', 'finally'
if (condition) {
    ...
} else {
    ...
}

try {
    ...
} catch (e) {
    ...
} finally {
    ...
}

// not good
function test()
{
    ...
}

// good
function test() {
    ...
}

// not good
var a, foo = 7, b,
    c, bar = 8

// good
var a,
    foo = 7,
    b, c, bar = 8
复制代码

4.7 单行注释

双斜线后,必须跟一个空格;

缩进与下一行代码保持一致;

可位于一个代码行的末尾,与代码间隔一个空格。

4.8 多行注释

最少三行, '*'后跟一个空格,具体参照右边的写法;

建议在以下情况下使用:

难于理解的代码段
可能存在错误的代码段
浏览器特殊的HACK代码
业务逻辑强相关的代码

/*
 * one space after '*'
 */
var x = 1
复制代码

4.9 文档注释

各类标签@param, @method等请参考 JSDoc中文、usejsdoc和JSDoc Guide;

建议在以下情况下使用:

所有常量
所有函数
所有类

/**
 * @func

 * @desc 一个带参数的函数

 * @param {string} a - 参数a

 * @param {number} b=1 - 参数b默认值为1

 * @param {string} c=1 - 参数c有两种支持的取值  1—表示x  2—表示xx

 * @param {object} d - 参数d为一个对象

 * @param {string} d.e - 参数d的e属性

 * @param {string} d.f - 参数d的f属性

 * @param {object[]} g - 参数g为一个对象数组

 * @param {string} g.h - 参数g数组中一项的h属性

 * @param {string} g.i - 参数g数组中一项的i属性

 * @param {string} [j] - 参数j是一个可选参数

 */

function foo(a, b, c, d, g, j) { ... }
复制代码

4.10 引号

最外层统一使用单引号。

4.11 变量命名

标准变量采用驼峰式命名(除了对象的属性外,主要是考虑到cgi返回的数据)
'ID'在变量名中全大写
'URL'在变量名中全大写
'Android'在变量名中大写第一个字母
'iOS'在变量名中小写第一个,大写后两个字母
常量全大写,用下划线连接
构造函数,大写第一个字母
jquery对象必须以'$'开头命名

var thisIsMyName;

var goodID;

var reportURL;

var AndroidVersion;

var iOSVersion;

var MAX_COUNT = 10;

function Person(name) {
  this.name = name;
}

// not good
var body = $('body');

// good
var $body = $('body');
复制代码

4.12 变量声明

  • 使用函数声明代替函数表达式。
  • 一个函数作用域中所有的变量声明尽量提到函数首部,用一个var或let声明,不允许出现两个连续的var或let声明。
  • 使用对象属性值的简写,并把简写的属性分组。
const name = 'name';
const age = 'age';

// bad
const obj = function(){
}
// good
const obj = {
    name,
    age,
    sex: '男',
    height: '170'
}
复制代码
  • 使用解构存取和使用多属性对象。因为解构能减少临时引用属性。
// bad
function getFullName(user){
    const fileName = user.firstName;
    const lastName = user.lastName;
    
    return `${firstName} ${lastName}`
}

// good
function getFullName(user){
    const { firstName, lastName } = user;
    
    return `${firstName} ${lastName}`
}

// best
function getFullName({ firstName, lastName }){
    return `${firstName} ${lastName}`
}
复制代码

4.13 函数

对上下文this的引用只能使用'_this', 'that', 'self'其中一个来命名;

不要给inline function命名;

参数之间用', '分隔,注意逗号后有一个空格。

直接给函数的参数指定默认值,不要使用一个变化的函数参数。

// bad
function handleThings(opts){
    opts = opts || {};
}

// good
function handleThings(opts = {}){ 
}
复制代码

4.14 箭头函数

  • 当你必须使用函数表达式(或传递一个匿名函数)时,使用箭头函数符号。
    因为箭头函数创造了新的 this 执行环境,通常情况下都能满足你的需求,而且这样的写法更为简洁。
// bad
[1, 2, 3].map(function (x) {
    return x * x;
})

// good
[1, 2, 3].map(x => {
    return x * x;
})
复制代码
  • 如果一个函数适合用一行写出并且只有一个参数,那就把花括号、圆括号和 return 都省略掉。如果不是,那就不要省略。
// good
[1, 2, 3].map(x => x * x);

// good
[1, 2, 3].map((total, x) => {
    return total + x;
})
复制代码

4.15 构造函数

  • 总是使用class,避免直接操作prototype。
// bad
function Queue(contents = []){
    this._queue = [...contents];
}
Queue.prototype.pop = function(){
    const value = this._queue[0];
    this._queue.splice(0, 1);
    return value;
}

// good
class Queue {
    constructor(contents = []){
        this._queue = [...contents];
    }
    pop(){
        const value = this._queue[0];
        this._queue.splice(0, 1);
        return value;
    }
}
复制代码
  • 使用 extends 继承。extends 是一个内建的原型继承方法并且不会破坏 instanceof 。
// bad
const inherits = require('inherits');
function PeekableQueue(contents) {
    Queue.apply(this, contents);
}
inherits(PeekableQueue, Queue);
PeekableQueue.prototype.peek = function() {
    return this._queue[0];
}

// good
class PeekableQueue extends Queue {
    peek() {
        return this._queue[0];
  }
}
复制代码
  • 方法可以返回 this 来帮助链式调用。
// bad
Jedi.prototype.jump = function() {
    this.jumping = true;
    return true;
};

Jedi.prototype.setHeight = function(height) {
    this.height = height;
};

const luke = new Jedi();
luke.jump(); // => true
luke.setHeight(20); // => undefined

// good
class Jedi {
    jump() {
        this.jumping = true;
        return this;
    }
    
    setHeight(height) {
        this.height = height;
        return this;
    }
}

const luke = new Jedi();

luke.jump().setHeight(20);
复制代码

4.16 数组、对象

对象属性名不需要加引号;

对象以缩进的形式书写,不要写在一行;

数组、对象最后不要有逗号。

4.17 括号

下列关键字后必须有大括号(即使代码块的内容只有一行):
if, else, for, while, do, switch, try, catch, finally, with。

4.18 null

适用场景:

初始化一个将来可能被赋值为对象的变量
与已经初始化的变量做比较
作为一个参数为对象的函数的调用传参
作为一个返回对象的函数的返回值

不适用场景:

不要用null来判断函数调用时有无传参
不要与未初始化的变量做比较

4.19 undefined

永远不要直接使用undefined进行变量判断;

使用typeof和字符串'undefined'对变量进行判断。

4.20 jshint

'===', '!=='代替'==', '!='

for-in里一定要有hasOwnProperty的判断;

不要在内置对象的原型上添加方法,如Array, Date;

不要在内层作用域的代码里声明了变量,之后却访问到了外层作用域的同名变量;

变量不要先使用后声明;

不要在一句代码中单单使用构造函数,记得将其赋值给某个变量;

不要在同个作用域下声明同名变量;

不要在一些不需要的地方加括号,例:delete(a.b);

不要使用未声明的变量(全局变量需要加到.jshintrc文件的globals属性里面);

不要声明了变量却不使用;

不要在应该做比较的地方做赋值;

debugger不要出现在提交的代码里;

数组中不要存在空元素;

不要在循环内部声明函数;

不要像这样使用构造函数,例:new function () { ... }, new Object

5.0 图片及第三方资源

5.1 存放目录

  • 静态类资源置于项目根目录下static文件夹
  • 配置类资源置于项目根目录下assets文件夹
  • 第三方库类资源置于项目根目录下components文件夹

5.2 格式

图片格式仅限于gif || png || jpg;
在保证视觉效果的情况下选择最小的图片格式与图片质量, 以减少加载时间;

5.3 命名

命名全部用小写英文字母 || 数字 || _ 的组合,其中不得包含汉字 || 空格 || 特殊字符;尽量用易懂的词汇, 便于团队其他成员理解; 另, 命名分头尾两部分, 用下划线隔开, 比如ad_left01.gif || btn_submit.gif;

5.4 其他

运用css sprite技术集中小的背景图或图标, 减小页面http请求, 但注意, 请务必在对应的sprite psd源图中划参考线, 并保存至img目录下。

6.0 JS框架&UI库

Vue、React、Angular、jQuery、小程序、公众号

6.1 jquery

6.1.1 jQuery-ui库

6.1.2 jQuery Plugin

6.2 Vue 注意点

  • 组件命名:
  1. 连字符:字母全小写且必须包含一个连字符(推荐,当直接在 DOM 中使用一个组件时)
Vue.component('my-component-name', { /* ... */ });
复制代码
  1. 大驼峰: 注意:当使用的不是字符串模板时,camelCase (驼峰式命名) 的 props属性需要转换为相对应的 kebab-case (连字符命名)
(1)、HTML模板:

Vue.component('child', {
// 在 JavaScript 中使用 camelCase
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})

(2)、字符串模板:

<!-- 在 HTML 中使用kebab-case -->
<child my-message="hello!"></child>
复制代码

6.2.1 Vue-ui库

移动端:

PC端:

6.2.2 Vue Plugin

6.2.3 Vue

6.3 React

6.3.1 React-ui库

移动端:

PC端:

6.3.2 React Plugin

6.4 Angular

6.4.1 Angular-ui库

移动端:

PC端:

6.3.2 Angular Plugin

6.5 小程序、公众号

6.5.1 小程序、公众号ui库

7.0 缓存

8.0 HTTP及接口请求

9.0 性能优化

10.0 终端兼容

10.1 分辨率兼容

10.1.1 移动端兼容

  • 不同的dpr下,加载不同的尺寸的图片
    如果有图片服务器,通过url获取参数,然后可以控制图片质量,也可以将图片裁剪成不同的尺寸。只需上传大图(@2x),其余小图都交给图片服务器处理,我们只要负责拼接url即可。
    如果没有图片服务器,准备多份不同尺寸的图片@1x@2x@3x

  • 不同的dpr下,1px宽的直线需要缩放0.5

    //方案一:缩小0.5倍来达到0.5px的效果
    border-bottom: 1px solid #ddd;
    -webkit-transform:scaleY(.5);
    -webkit-transform-origin:0 0;
    
    //方案二:添加如下的meta标签,设置viewport(scale 0.5)
    <meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5, minimum-scale=0.5,user-scalable=no">  
    复制代码

10.2 浏览器版本兼容

11.0 自动化测试

11.1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值