2019独角兽企业重金招聘Python工程师标准>>>

前端开发规范

一、HTML

1.语义化标签

HTML5 提供了很多语义化元素,更好地帮助描述内容。希望你能从这些丰富的标签库中受益。

<!-- bad -->
<div id="main"><div class="article"><div class="header"><h1>Blog post</h1><p>Published: <span>21st Feb, 2015</span></p></div><p>…</p></div>
</div>
<!-- good -->
<main><article><header><h1>Blog post</h1><p>Published: <time datetime="2015-02-21">21st Feb, 2015</time></p></header><p>…</p></article>
</main>

 

请确保正确使用语义化的标签,错误的用法甚至不如保守的用法。

<!-- bad -->
<h1><figure><img alt=Company src=logo.png></figure>
</h1><!-- good -->
<h1><img alt=Company src=logo.png>
</h1>

简洁

确保代码简洁,不要再采用XHTML的旧做法。

<!-- bad -->
<!doctype html>
<html lang=en><head><meta http-equiv=Content-Type content="text/html; charset=utf-8" /><title>Contact</title><link rel=stylesheet href=style.css type=text/css /></head><body><h1>Contact me</h1><label>Email address:<input type=email placeholder=you@email.com required=required /></label><script src=main.js type=text/javascript></script></body>
</html>
<!-- good -->
<!doctype html>
<html lang=en><meta charset=utf-8><title>Contact</title><link rel=stylesheet href=style.css><h1>Contact me</h1><label>Email address:<input type=email placeholder=you@email.com required></label><script src=main.js></script>
</html>

HTML5 doctype

为每个 HTML 页面的第一行添加标准模式(standard mode)的声明,这样能够确保在每个浏览器中拥有一致的展现。

<!DOCTYPE html>
<html><head></head>
</html>

语言属性

根据 HTML5 规范:

强烈建议为 html 根元素指定 lang 属性,从而为文档设置正确的语言。这将有助于语音合成工具确定其所应该采用的发音,有助于翻译工具确定其翻译时所应遵守的规则等等。

更多关于 lang 属性的知识可以从 此规范 中了解。

这里列出了语言代码表。

<html lang="en"><!-- ... -->
</html>

IE 兼容模式

IE 支持通过特定的 <meta> 标签来确定绘制当前页面所应该采用的 IE 版本。除非有强烈的特殊需求,否则最好是设置为 edge mode,从而通知 IE 采用其所支持的最新的模式。

阅读这篇 stack overflow 上的文章可以获得更多有用的信息。

<meta http-equiv="X-UA-Compatible" content="IE=Edge">

字符编码

通过明确声明字符编码,能够确保浏览器快速并容易的判断页面内容的渲染方式。这样做的好处是,可以避免在 HTML 中使用字符实体标记(character entity),从而全部与文档编码一致(一般采用 UTF-8 编码)。

<head><meta charset="UTF-8">
</head>

可用性

可用性不应该是事后才考虑的事情。你可以通过简单的修改做出不错的效果,例如:

  • 正确使用alt属性
  • 确保链接和按钮正确使用(不要用<div class=button>这种粗暴的做法)
  • 不依赖于颜色来传达信息
  • 给表单做好lable标记
<!-- bad --><h1><img alt="Logo" src="logo.png"></h1><!-- good --><h1><img alt="My Company, Inc." src="logo.png"></h1>

性能

除非有非要在加载内容前加载脚本的必要性由,不然别这样做,这样会阻碍网页渲染。如果你的样式表很大,必须独立放到一个文件里。两次HTTP 请求不会显著降低性能。

<!-- bad -->
<!doctype html>
<meta charset=utf-8>
<script src=analytics.js></script>
<title>Hello, world.</title>
<p>...</p><!-- good -->
<!doctype html>
<meta charset=utf-8>
<title>Hello, world.</title>
<p>...</p>
<script src=analytics.js></script>

属性顺序

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

id class name data-xxx src, for, type, href title, alt aria-xxx, role value style

二、CSS

分号

不能漏写分号

/* bad */
div {color: red
}/* good */
div {color: red;
}

尽量不要改变元素默认行为。保持默认的文本流。比如,移出一个图片下面的一个白块,不影响原本的显示:

/* bad */
img {display: block;
}/* good */
img {vertical-align: middle;
}

类似的,尽量不要改变浮动方式。

/* bad */
div {width: 100px;position: absolute;right: 0;
}/* good */
div {width: 100px;margin-left: auto;
}

选择器

紧密耦合DOM选择器,三个层级以上建议加class:

/* bad */
div:first-of-type :last-child > p ~ */* good */
div:first-of-type .info

避免不必要的写法:

/* bad */
img[src$=svg], ul > li:first-child {opacity: 0;
}/* good */
[src$=svg], ul > :first-child {opacity: 0;
}

指明

不要让代码难于重写,让选择器更精确,减少ID、避免使用!important

/* bad */
.bar {color: green !important;
}
.foo {color: red;
}/* good */
.foo.bar {color: green;
}
.foo {color: red;
}

覆盖

覆盖样式会使维护和调试更困难,所以要尽量避免。

/* bad */
li {visibility: hidden;
}
li:first-child {visibility: visible;
}/* good */
li + li {visibility: hidden;
}

继承

不要把可继承的样式重复声明:

/* bad */
div h1, div p {text-shadow: 0 1px 0 #fff;
}/* good */
div {text-shadow: 0 1px 0 #fff;
}

简洁性

保持代码的简洁。使用属性缩写。不必要的值不用写。

/* bad */
div {transition: all 1s;top: 50%;margin-top: -10px;padding-top: 5px;padding-right: 10px;padding-bottom: 20px;padding-left: 10px;
}/* good */
div {transition: 1s;top: calc(50% - 10px);padding: 5px 10px 20px;
}

语言

能用英文的时候不用数字。

/* bad */
:nth-child(2n + 1) {transform: rotate(360deg);
}/* good */
:nth-child(odd) {transform: rotate(1turn);
}

动画

除了变形和改变透明度用animation,其他尽量使用transition。

/* bad */
div:hover {animation: move 1s forwards;
}
@keyframes move {100% {margin-left: 100px;}
}/* good */
div:hover {transition: 1s;transform: translateX(100px);
}

单位

可以不用单位时就不用。建议用rem。时间单位用s比ms好。

/* bad */
div {margin: 0px;font-size: .9em;line-height: 22px;transition: 500ms;
}/* good */
div {margin: 0;font-size: .9rem;line-height: 1.5;transition: .5s;
}

颜色

需要做透明效果是用rgba,否则都用16进制表示:

/* bad */
div {color: hsl(103, 54%, 43%);
}/* good */
div {color: #5a3;
}

绘图

减少HTTPS请求,尽量用CSS绘图替代图片:

/* bad */
div::before {content: url(white-circle.svg);
}/* good */
div::before {content: "";display: block;width: 20px;height: 20px;border-radius: 50%;background: #fff;
}

注释

/* bad */
div {// position: relative;transform: translateZ(0);
}/* good */
div {/* position: relative; */will-change: transform;
}

语法

  • 用两个空格来代替制表符(tab) -- 这是唯一能保证在所有环境下获得一致展现的方法。
  • 为选择器分组时,将单独的选择器单独放在一行。
  • 为了代码的易读性,在每个声明块的左花括号前添加一个空格。
  • 声明块的右花括号应当单独成行。
  • 每条声明语句的 : 后应该插入一个空格。
  • 为了获得更准确的错误报告,每条声明都应该独占一行。
  • 所有声明语句都应当以分号结尾。最后一条声明语句后面的分号是可选的,但是,如果省略这个分号,你的代码可能更易出错。
  • 对于以逗号分隔的属性值,每个逗号后面都应该插入一个空格(例如,box-shadow)。
  • 不要在 rgb()、rgba()、hsl()、hsla() 或 rect() 值的内部的逗号后面插入空格。这样利于从多个属性值(既加逗号也加空格)中区分多个颜色值(只加逗号,不加空格)。
/* Bad CSS */
.selector, .selector-secondary, .selector[type=text] {padding:15px;margin:0px 0px 15px;background-color:rgba(0, 0, 0, 0.5);box-shadow:0px 1px 2px #CCC,inset 0 1px 0 #FFFFFF
}/* Good CSS */
.selector,
.selector-secondary,
.selector[type="text"] {padding: 15px;margin-bottom: 15px;background-color: rgba(0,0,0,.5);box-shadow: 0 1px 2px #ccc, inset 0 1px 0 #fff;
}

id及class命名

*class应以功能过内容命名,不以表现形式命名,通用且有意义的词

*class与id单词字母小写,多个单词组成时,使用中划线“-”分隔

激活及hover的效果class

使用on作为激活状态的class,使用hover作为移上元素(hover)的class

样式的声明顺序

1、定位

2、盒模型

3、关于文字

4、关于颜色,背景

5、其他,如:cursor:pointer

.declaration-order {/*定位 */position: absolute;top: 0;right: 0;bottom: 0;left: 0;z-index: 100;/* 盒模型 */display: block;box-sizing: border-box;width: 100px;height: 100px;padding: 10px;border: 1px solid #e5e5e5;border-radius: 3px;margin: 10px;float: right;overflow: hidden;/* 关于文字 */font: normal 13px "Helvetica Neue", sans-serif;line-height: 1.5;text-align: center;/* 关于颜色,背景 */background-color: #f5f5f5;color: #fff;opacity: .8;/*其他 */cursor: pointer;}

less语法规范

1.变量,混合的使用

变量,混合,允许我们单独定义一系列通用的样式,然后在需要的时候去调用。所以一些公共的样式规则可以单独在一个less文件中定义,其他地方调用,在做全局样式调整时能很方便的修改

// LESS@color: #4D926F;#header {color: @color;
}
h2 {color: @color;
}/* 生成的 CSS */#header {color: #4D926F;
}
h2 {color: #4D926F;
}//LESS
.bordered {border-top: dotted 1px black;border-bottom: solid 2px black;
}#menu a {color: #111;.bordered;
}
.post a {color: red;.bordered;
}/* 生成的 CSS */
#menu a {color: #111;border-top: dotted 1px black;border-bottom: solid 2px black;
}
.post a {color: red;border-top: dotted 1px black;border-bottom: solid 2px black;
}

2.嵌套规则(避免嵌套层级过多)

将嵌套深度限制在2-3级。对于超过3级的嵌套,给予重新评估。这可以避免出现过于详实的CSS选择器。 避免大量的嵌套规则。当可读性受到影响时,将之打断。推荐避免出现多于20行的嵌套规则出现。

#header {color: black;.navigation {font-size: 12px;}.logo {width: 300px;&:hover { text-decoration: none }}
}

3.命名空间

有时候,你可能为了更好组织CSS或者单纯是为了更好的封装,将一些变量或者混合模块打包起来, 你可以像下面这样在#bundle中定义一些属性集之后可以重复使用:

#bundle {.button () {display: block;border: 1px solid black;background-color: grey;&:hover { background-color: white }}.tab { ... }.citation { ... }
}
/*你只需要在 #header a中像这样引入 .button:*/
#header a {color: orange;#bundle > .button;
}

以上HTML和CSS的规范大部分参考github上的frontend-guidelines及编码规范by@mdo(后面几个自己新增

三、JavaScript

javascript规范使用的是Standard标准,其好处可点击超链接查看,npm,github等都是使用的此标准。 下文copy的Standard Style的具体规则,配合eslint使用

1. 使用两个空格进行缩进。

eslint: indent

function hello (name) {console.log('hi', name)
}

2.除需要转义的情况外,字符串统一使用单引号。

eslint: quotes

console.log('hello there')
$("<div class='box'>")

3.不要定义未使用的变量。

eslint: no-unused-vars

function myFunction () {var result = something()   // ✗ avoid
}

4.关键字后面加空格。

eslint: keyword-spacing

if (condition) { ... }   // ✓ ok
if(condition) { ... }    // ✗ avoid

5.函数声明时括号与函数名间加空格。

eslint: space-before-function-paren

function name (arg) { ... }   // ✓ ok
function name(arg) { ... }    // ✗ avoidrun(function () { ... })      // ✓ ok
run(function() { ... })       // ✗ avoid

6.始终使用 === 替代 ==。

例外: obj == null 可以用来检查 null || undefined。

eslint: eqeqeq

if (name === 'John')   // ✓ ok
if (name == 'John')    // ✗ avoid
if (name !== 'John')   // ✓ ok
if (name != 'John')    // ✗ avoid

7.字符串拼接操作符 (Infix operators) 之间要留空格。

eslint: space-infix-ops

// ✓ ok
var x = 2
var message = 'hello, ' + name + '!'
// ✗ avoid
var x=2
var message = 'hello, '+name+'!'

8.逗号后面加空格。

eslint: comma-spacing

// ✓ ok
var list = [1, 2, 3, 4]
function greet (name, options) { ... }
// ✗ avoid
var list = [1,2,3,4]
function greet (name,options) { ... }

9.else 关键字要与花括号保持在同一行。

eslint: brace-style

// ✓ ok
if (condition) {// ...
} else {// ...
}
// ✗ avoid
if (condition)
{// ...
}
else
{// ...
}

10.多行 if 语句的的括号不能省。

eslint: curly

// ✓ ok
if (options.quiet !== true) console.log('done')
// ✓ ok
if (options.quiet !== true) {console.log('done')
}
// ✗ avoid
if (options.quiet !== true)console.log('done')

11.不要丢掉异常处理中err参数。

eslint: handle-callback-err

// ✓ ok
run(function (err) {if (err) throw errwindow.alert('done')
})
// ✗ avoid
run(function (err) {window.alert('done')
})

12.使用浏览器全局变量时加上 window. 前缀。

例外: document, console and navigator

eslint: no-undef

window.alert('hi')   // ✓ ok

13.不允许有连续多行空行。

eslint: no-multiple-empty-lines

// ✓ ok
var value = 'hello world'
console.log(value)
// ✗ avoid
var value = 'hello world'console.log(value)

14.对于三元运算符 ? 和 : 与他们所负责的代码处于同一行。

eslint: operator-linebreak

// ✓ ok
var location = env.development ? 'localhost' : 'www.api.com'// ✓ ok
var location = env.development? 'localhost': 'www.api.com'
// ✗ avoid
var location = env.development ?'localhost' :'www.api.com'

15.每个 var 关键字单独声明一个变量。

eslint: one-var

// ✓ ok
var silent = true
var verbose = true
// ✗ avoid
var silent = true, verbose = true// ✗ avoid
var silent = true,verbose = true

16.条件语句中赋值语句使用括号包起来。这样使得代码更加清晰可读,而不会认为是将条件判断语句的全等号(===)错写成了等号(=)。

eslint: no-cond-assign

// ✓ ok
while ((m = text.match(expr))) {// ...
}// ✗ avoid
while (m = text.match(expr)) {// ...
}

17.单行代码块两边加空格。

eslint: block-spacing

function foo () {return true}    // ✗ avoid
function foo () { return true }  // ✓ ok

18.对于变量和函数名统一使用驼峰命名法。

eslint: camelcase

function my_function () { }    // ✗ avoid
function myFunction () { }     // ✓ okvar my_var = 'hello'           // ✗ avoid
var myVar = 'hello'            // ✓ ok

19.不允许有多余的行末逗号。

eslint: comma-dangle

var obj = {message: 'hello',   // ✗ avoid}

20.始终将逗号置于行末。

eslint: comma-style

var obj = {foo: 'foo',bar: 'bar'   // ✗ avoid}var obj = {foo: 'foo',bar: 'bar'   // ✓ ok}

21.文件末尾留一空行。

elint: eol-last

22.函数调用时标识符与括号间不留间隔。

eslint: func-call-spacing

console.log ('hello') // ✗ avoid
console.log('hello')  // ✓ ok

23.键值对当中冒号与值之间要留空白。

eslint: key-spacing

var obj = { 'key' : 'value' }    // ✗ avoid
var obj = { 'key' :'value' }     // ✗ avoid
var obj = { 'key':'value' }      // ✗ avoid
var obj = { 'key': 'value' }     // ✓ ok

24.构造函数要以大写字母开头。

eslint: new-cap

function animal () {}
var dog = new animal()    // ✗ avoid
function Animal () {}
var dog = new Animal()    // ✓ ok

25.无参的构造函数调用时要带上括号。

eslint: new-parens

function Animal () {}
var dog = new Animal    // ✗ avoid
var dog = new Animal()  // ✓ ok

26.对象中定义了存值器,一定要对应的定义取值器。

eslint: accessor-pairs

var person = {set name (value) {    // ✗ avoidthis.name = value}
}
var person = {set name (value) {this.name = value},get name () {         // ✓ okreturn this.name}
}

27.子类的构造器中一定要调用 super

eslint: constructor-super

class Dog {constructor () {super()   // ✗ avoid}
}class Dog extends Mammal {constructor () {super()   // ✓ ok}
}

28.使用数组字面量而不是构造器。

eslint: no-array-constructor

var nums = new Array(1, 2, 3)   // ✗ avoid
var nums = [1, 2, 3]            // ✓ ok

29.避免使用 arguments.callee 和 arguments.caller。

eslint: no-caller

function foo (n) {if (n <= 0) returnarguments.callee(n - 1)   // ✗ avoid
}function foo (n) {if (n <= 0) returnfoo(n - 1)
}

30.避免对类名重新赋值。

eslint: no-class-assign

class Dog {}
Dog = 'Fido'    // ✗ avoid

31.避免修改使用 const 声明的变量。

eslint: no-const-assign

const score = 100
score = 125       // ✗ avoid

32.避免使用常量作为条件表达式的条件(循环语句除外)。

eslint: no-constant-condition

if (false) {    // ✗ avoid// ...
}if (x === 0) {  // ✓ ok// ...
}while (true) {  // ✓ ok// ...
}

33.正则中不要使用控制符。

eslint: no-control-regex

var pattern = /\x1f/    // ✗ avoid
var pattern = /\x20/    // ✓ ok

34.不要使用 debugger。

eslint: no-debugger

function sum (a, b) {debugger      // ✗ avoidreturn a + b
}

35.不要对变量使用 delete 操作。

eslint: no-delete-var

var name
delete name     // ✗ avoid

36.不要定义冗余的函数参数。

eslint: no-dupe-args

function sum (a, b, a) {  // ✗ avoid// ...
}function sum (a, b, c) {  // ✓ ok// ...
}

37.类中不要定义冗余的属性。

eslint: no-dupe-class-members

class Dog {bark () {}bark () {}    // ✗ avoid
}

38.对象字面量中不要定义重复的属性。

eslint: no-dupe-keys

var user = {name: 'Jane Doe',name: 'John Doe'    // ✗ avoid
}

39.switch 语句中不要定义重复的 case 分支。

eslint: no-duplicate-case

switch (id) {case 1:// ...case 1:     // ✗ avoid
}

40.同一模块有多个导入时一次性写完。

eslint: no-duplicate-imports

import { myFunc1 } from 'module'
import { myFunc2 } from 'module'          // ✗ avoidimport { myFunc1, myFunc2 } from 'module' // ✓ ok

41.正则中不要使用空字符。

eslint: no-empty-character-class

const myRegex = /^abc[]/      // ✗ avoid
const myRegex = /^abc[a-z]/   // ✓ ok

42.不要解构空值。

eslint: no-empty-pattern

const { a: {} } = foo         // ✗ avoid
const { a: { b } } = foo      // ✓ ok

43.不要使用 eval()。

eslint: no-eval

eval( "var result = user." + propName ) // ✗ avoid
var result = user[propName]             // ✓ ok

44.catch 中不要对错误重新赋值。

eslint: no-ex-assign

try {// ...
} catch (e) {e = 'new value'             // ✗ avoid
}try {// ...
} catch (e) {const newVal = 'new value'  // ✓ ok
}

45.不要扩展原生对象。

eslint: no-extend-native

Object.prototype.age = 21     // ✗ avoid

46.避免多余的函数上下文绑定。

eslint: no-extra-bind

const name = function () {getName()
}.bind(user)    // ✗ avoidconst name = function () {this.getName()
}.bind(user)    // ✓ ok

47.避免不必要的布尔转换。

eslint: no-extra-boolean-cast

const result = true
if (!!result) {   // ✗ avoid// ...
}const result = true
if (result) {     // ✓ ok// ...
}

48.不要使用多余的括号包裹函数。

eslint: no-extra-parens

const myFunc = (function () { })   // ✗ avoid
const myFunc = function () { }     // ✓ ok

49.switch 一定要使用 break 来将条件分支正常中断。

eslint: no-fallthrough

switch (filter) {case 1:doSomething()    // ✗ avoidcase 2:doSomethingElse()
}switch (filter) {case 1:doSomething()break           // ✓ okcase 2:doSomethingElse()
}switch (filter) {case 1:doSomething()// fallthrough // ✓ okcase 2:doSomethingElse()
}

50.不要省去小数点前面的0。

eslint: no-floating-decimal

const discount = .5      // ✗ avoid
const discount = 0.5     // ✓ ok

51.避免对声明过的函数重新赋值。

eslint: no-func-assign

function myFunc () { }
myFunc = myOtherFunc    // ✗ avoid

52.不要对全局只读对象重新赋值。

eslint: no-global-assign

window = {}     // ✗ avoid

53.注意隐式的 eval()。

eslint: no-implied-eval

setTimeout("alert('Hello world')")                   // ✗ avoid
setTimeout(function () { alert('Hello world') })     // ✓ ok

54.嵌套的代码块中禁止再定义函数。

eslint: no-inner-declarations

if (authenticated) {function setAuthUser () {}    // ✗ avoid
}

55.不要向 RegExp 构造器传入非法的正则表达式。

eslint: no-invalid-regexp

RegExp('[a-z')    // ✗ avoid
RegExp('[a-z]')   // ✓ ok

56.不要使用非法的空白符。

eslint: no-irregular-whitespace

function myFunc () /*<NBSP>*/{}   // ✗ avoid

57.禁止使用 iterator

eslint: no-iterator

Foo.prototype.__iterator__ = function () {}   // ✗ avoid

58.外部变量不要与对象属性重名。

eslint: no-label-var

var score = 100
function game () {score: 50         // ✗ avoid
}

59.不要使用标签语句

eslint: no-labels

label:while (true) {break label     // ✗ avoid}

60.不要书写不必要的嵌套代码块。

eslint: no-lone-blocks

function myFunc () {{                   // ✗ avoidmyOtherFunc()}
}function myFunc () {myOtherFunc()       // ✓ ok
}

61.不要混合使用空格与制表符作为缩进。

eslint: no-mixed-spaces-and-tabs

62.除了缩进,不要使用多个空格。

eslint: no-multi-spaces

const id =    1234    // ✗ avoid
const id = 1234       // ✓ ok

63.不要使用多行字符串。

eslint: no-multi-str

const message = 'Hello \ world'     // ✗ avoid

64.new 创建对象实例后需要赋值给变量。

eslint: no-new

new Character()                     // ✗ avoid
const character = new Character()   // ✓ ok

65.禁止使用 Function 构造器。

eslint: no-new-func

var sum = new Function('a', 'b', 'return a + b')    // ✗ avoid

66.禁止使用 Object 构造器。

eslint: no-new-object

let config = new Object()   // ✗ avoid

67.禁止使用 new require。

eslint: no-new-require

const myModule = new require('my-module')    // ✗ avoid

68.禁止使用 Symbol 构造器。

eslint: no-new-symbol

const foo = new Symbol('foo')   // ✗ avoid

69.禁止使用原始包装器。

eslint: no-new-wrappers

const message = new String('hello')   // ✗ avoid

70.不要将全局对象的属性作为函数调用。

eslint: no-obj-calls

const math = Math()   // ✗ avoid

71.不要使用八进制字面量。

eslint: no-octal

const num = 042     // ✗ avoid
const num = '042'   // ✓ ok

72.字符串字面量中也不要使用八进制转义字符。

eslint: no-octal-escape

const copyright = 'Copyright \251'  // ✗ avoid

73.使用 __dirname 和 __filename 时尽量避免使用字符串拼接。

eslint: no-path-concat

const pathToFile = __dirname + '/app.js'            // ✗ avoid
const pathToFile = path.join(__dirname, 'app.js')   // ✓ ok

74.使用 getPrototypeOf 来替代 proto

eslint: no-proto

const foo = obj.__proto__               // ✗ avoid
const foo = Object.getPrototypeOf(obj)  // ✓ ok

75.不要重复声明变量。

eslint: no-redeclare

let name = 'John'
let name = 'Jane'     // ✗ avoidlet name = 'John'
name = 'Jane'         // ✓ ok

76.正则中避免使用多个空格。

eslint: no-regex-spaces

const regexp = /test value/   // ✗ avoidconst regexp = /test {3}value/  // ✓ ok
const regexp = /test value/     // ✓ ok

77.return 语句中的赋值必需有括号包裹。

eslint: no-return-assign

function sum (a, b) {return result = a + b     // ✗ avoid
}function sum (a, b) {return (result = a + b)   // ✓ ok
}

78.避免将变量赋值给自己。

eslint: no-self-assign

name = name   // ✗ avoid

79.避免将变量与自己进行比较操作。

esint: no-self-compare

if (score === score) {}   // ✗ avoid

80.避免使用逗号操作符。

eslint: no-sequences

if (doSomething(), !!test) {}   // ✗ avoid

81.不要随意更改关键字的值。

eslint: no-shadow-restricted-names

let undefined = 'value'     // ✗ avoid

82.禁止使用稀疏数组(Sparse arrays)。

eslint: no-sparse-arrays

let fruits = ['apple',, 'orange']       // ✗ avoid

83.不要使用制表符。

eslint: no-tabs

84.正确使用 ES6 中的字符串模板。

eslint: no-template-curly-in-string

const message = 'Hello ${name}'   // ✗ avoid
const message = `Hello ${name}`   // ✓ ok

85.使用 this 前请确保 super() 已调用。

eslint: no-this-before-super

class Dog extends Animal {constructor () {this.legs = 4     // ✗ avoidsuper()}
}

86.用 throw 抛错时,抛出 Error 对象而不是字符串。

eslint: no-throw-literal

throw 'error'               // ✗ avoid
throw new Error('error')    // ✓ ok

87.行末不留空格。

eslint: no-trailing-spaces

88.不要使用 undefined 来初始化变量。

eslint: no-undef-init

let name = undefined    // ✗ avoidlet name
name = 'value'          // ✓ ok

89.循环语句中注意更新循环变量。

eslint: no-unmodified-loop-condition

for (let i = 0; i < items.length; j++) {...}    // ✗ avoid
for (let i = 0; i < items.length; i++) {...}    // ✓ ok

90.如果有更好的实现,尽量不要使用三元表达式。

eslint: no-unneeded-ternary

let score = val ? val : 0     // ✗ avoid
let score = val || 0          // ✓ ok

91.return,throw,continue 和 break 后不要再跟代码。

eslint: no-unreachable

function doSomething () {return trueconsole.log('never called')     // ✗ avoid
}

92.finally 代码块中不要再改变程序执行流程。

eslint: no-unsafe-finally

try {// ...
} catch (e) {// ...
} finally {return 42     // ✗ avoid
}

93.关系运算符的左值不要做取反操作。

eslint: no-unsafe-negation

if (!key in obj) {}       // ✗ avoid

94.避免不必要的 .call() 和 .apply()。

eslint: no-useless-call

sum.call(null, 1, 2, 3)   // ✗ avoid

95.避免使用不必要的计算值作对象属性。

eslint: no-useless-computed-key

const user = { ['name']: 'John Doe' }   // ✗ avoid
const user = { name: 'John Doe' }       // ✓ ok

96.禁止多余的构造器。

eslint: no-useless-constructor

class Car {constructor () {      // ✗ avoid}
}

97.禁止不必要的转义。

eslint: no-useless-escape

let message = 'Hell\o'  // ✗ avoid

98.import, export 和解构操作中,禁止赋值到同名变量。

eslint: no-useless-rename

import { config as config } from './config'     // ✗ avoid
import { config } from './config'               // ✓ ok

99.属性前面不要加空格。

eslint: no-whitespace-before-property

user .name      // ✗ avoid
user.name       // ✓ ok

100.禁止使用 with。

eslint: no-with

with (val) {...}    // ✗ avoid

101.对象属性换行时注意统一代码风格。

eslint: object-property-newline

const user = {name: 'Jane Doe', age: 30,username: 'jdoe86'            // ✗ avoid
}const user = { name: 'Jane Doe', age: 30, username: 'jdoe86' }    // ✓ okconst user = {name: 'Jane Doe',age: 30,username: 'jdoe86'
}

102.代码块中避免多余留白。

eslint: padded-blocks

if (user) {// ✗ avoidconst name = getName()}if (user) {const name = getName()    // ✓ ok
}

103.展开运算符与它的表达式间不要留空白。

eslint: rest-spread-spacing

fn(... args)    // ✗ avoid
fn(...args)     // ✓ ok

104.遇到分号时空格要后留前不留。

eslint: semi-spacing

for (let i = 0 ;i < items.length ;i++) {...}    // ✗ avoid
for (let i = 0; i < items.length; i++) {...}    // ✓ ok

105.代码块首尾留空格。

eslint: space-before-blocks

if (admin){...}     // ✗ avoid
if (admin) {...}    // ✓ ok

106.圆括号间不留空格

eslint: space-in-parens

getName( name )     // ✗ avoid
getName(name)       // ✓ ok

107.一元运算符后面跟一个空格。

eslint: space-unary-ops

typeof!admin        // ✗ avoid
typeof !admin        // ✓ ok

108.注释首尾留空格。

eslint: spaced-comment

//comment // ✗ avoid
// comment // ✓ ok/*comment*/         // ✗ avoid
/* comment */       // ✓ ok

109.模板字符串中变量前后不加空格。

eslint: template-curly-spacing

const message = `Hello, ${ name }`    // ✗ avoid
const message = `Hello, ${name}`      // ✓ ok

110.检查 NaN 的正确姿势是使用 isNaN()。

eslint: use-isnan

if (price === NaN) { }      // ✗ avoid
if (isNaN(price)) { }       // ✓ ok

111.用合法的字符串跟 typeof 进行比较操作。

eslint: valid-typeof

typeof name === 'undefimed'     // ✗ avoid
typeof name === 'undefined'     // ✓ ok

112.自调用匿名函数 (IIFEs) 使用括号包裹。

eslint: wrap-iife

const getName = function () { }()     // ✗ avoidconst getName = (function () { }())   // ✓ ok
const getName = (function () { })()   // ✓ ok

113.yield * 中的 * 前后都要有空格。

eslint: yield-star-spacing

yield* increment()    // ✗ avoid
yield * increment()   // ✓ ok

114.请书写优雅的条件语句(avoid Yoda conditions)。

eslint: yoda

if (42 === age) { }    // ✗ avoid
if (age === 42) { }    // ✓ ok

115.使用分号。

eslint: semi

window.alert('hi')   // ✗ avoid
window.alert('hi');  // ✓ ok

116.不要使用 (, [, or ` 等作为一行的开始。在没有分号的情况下代码压缩后会导致报错,而坚持这一规范则可避免出错。

** eslint: no-unexpected-multiline **

// ✓ ok
;(function () {window.alert('ok')
}())// ✗ avoid
(function () {window.alert('ok')
}())
// ✓ ok
;[1, 2, 3].forEach(bar)// ✗ avoid
[1, 2, 3].forEach(bar)
// ✓ ok
;`hello`.indexOf('o')// ✗ avoid
`hello`.indexOf('o')

备注:上面的写法只能说聪明过头了。

相比更加可读易懂的代码,那些看似投巧的写法是不可取的。

譬如:

;[1, 2, 3].forEach(bar)

建议的写法是:

var nums = [1, 2, 3]
nums.forEach(bar)

es6语法规范

1.let 取代 var

ES6 提出了两个新的声明变量的命令:let和const。其中,let完全可以取代var,因为两者语义相同,而且let没有副作用。

2.全局常量const

在全局环境,不应该设置变量,只应设置常量

好处:const优于let有几个原因。一个是const可以提醒阅读程序的人,这个变量不应该改变;另一个是const比较符合函数式编程思想,运算不改变值,只是新建值,而且这样也有利于将来的分布式运算;最后一个原因是 JavaScript 编译器会对const进行优化,所以多使用const,有利于提高程序的运行效率,也就是说letconst的本质区别,其实是编译器内部的处理不同。 const声明常量还有两个好处,一是阅读代码的人立刻会意识到不应该修改这个值,二是防止了无意间修改变量值所导致的错误。

3.使用解构赋值

使用数组成员对变量赋值时,优先使用解构赋值。

const arr = [1, 2, 3, 4];// bad
const first = arr[0];
const second = arr[1];// good
const [first, second] = arr;

函数的参数如果是对象的成员,优先使用解构赋值。

// bad
function getFullName(user) {const firstName = user.firstName;const lastName = user.lastName;
}// good
function getFullName(obj) {const { firstName, lastName } = obj;
}// best
function getFullName({ firstName, lastName }) {
}

如果函数返回多个值,优先使用对象的解构赋值,而不是数组的解构赋值。这样便于以后添加返回值,以及更改返回值的顺序。

// bad
function processInput(input) {return [left, right, top, bottom];
}// good
function processInput(input) {return { left, right, top, bottom };
}const { left, right } = processInput(input);

4.对象

对象尽量静态化,一旦定义,就不得随意添加新的属性。如果添加属性不可避免,要使用Object.assign方法。

// bad
const a = {};
a.x = 3;// if reshape unavoidable
const a = {};
Object.assign(a, { x: 3 });// good
const a = { x: null };
a.x = 3;

如果对象的属性名是动态的,可以在创造对象的时候,使用属性表达式定义。

// bad
const obj = {id: 5,name: 'San Francisco',
};
obj[getKey('enabled')] = true;// good
const obj = {id: 5,name: 'San Francisco',[getKey('enabled')]: true,
};

另外,对象的属性和方法,尽量采用简洁表达法,这样易于描述和书写。

var ref = 'some value';// bad
const atom = {ref: ref,value: 1,addValue: function (value) {return atom.value + value;},
};// good
const atom = {ref,value: 1,addValue(value) {return atom.value + value;},
};

5.数组

使用扩展运算符(...)拷贝数组。

// bad
const len = items.length;
const itemsCopy = [];
let i;for (i = 0; i < len; i++) {itemsCopy[i] = items[i];
}// good
const itemsCopy = [...items];

使用 Array.from 方法,将类似数组的对象转为数组。

const foo = document.querySelectorAll('.foo');
const nodes = Array.from(foo);

6.函数

立即执行函数可以写成箭头函数的形式。

(() => {console.log('Welcome to the Internet.');
})();

那些需要使用函数表达式的场合,尽量用箭头函数代替。因为这样更简洁,而且绑定了 this。

// bad
[1, 2, 3].map(function (x) {return x * x;
});// good
[1, 2, 3].map((x) => {return x * x;
});// best
[1, 2, 3].map(x => x * x);

简单的、单行的、不会复用的函数,建议采用箭头函数。如果函数体较为复杂,行数较多,还是应该采用传统的函数写法。

7.Map结构

注意区分 Object 和 Map,只有模拟现实世界的实体对象时,才使用 Object。如果只是需要key: value的数据结构,使用 Map 结构。因为 Map 有内建的遍历机制。

let map = new Map(arr);for (let key of map.keys()) {console.log(key);
}for (let value of map.values()) {console.log(value);
}for (let item of map.entries()) {console.log(item[0], item[1]);
}

8.class

总是用 Class,取代需要 prototype 的操作。因为 Class 的写法更简洁,更易于理解。

// 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实现继承,因为这样更简单,不会有破坏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];}
}

9.使用promise时

一般来说,不要在then方法里面定义失败状态的回调函数(即then的第二个参数),总是使用catch方法

// bad
promise.then(function(data) {// success}, function(err) {// error});// good
promise.then(function(data) { //cb// success}).catch(function(err) {// error});

新增

i++

尽量不要使用i++,尽量使用i+=1;(除了for循环)

四、vue规范

1.vue方法放置顺序

1.1 components

1.2 props

1.3 data

1.4 created

1.5 mounted

1.6 activited

1.7 update

1.8 beforeRouteUpdate

1.9 metods

1.10 filter

1.11 computed

1.12 watch

2.method 自定义方法命名

2.1 动宾短语(good:jumpPage、openCarInfoDialog)(bad:go、nextPage、show、open、login)

2.2 ajax 方法以 get、post 开头,以 data 结尾(good:getListData、postFormData)(bad:takeData、confirmData、getList、postForm)

2.3 事件方法以 on 开头(onTypeChange、onUsernameInput)

2.4 init、refresh 单词除外

2.5 尽量使用常用单词开头(set、get、open、close、jump)

2.6 驼峰命名(good: getListData)(bad: get_list_data、getlistData)

3.生命周期方法注意点

3.1 不在 mounted、created 之类的方法写逻辑,取 ajax 数据,

3.2 在 created 里面监听 Bus 事件

4.基于模块开发

原则:每一个vue组件首先必须专注于解决一个单一的问题,独立的,可复用的,微小的和可测试的。 如果你的组件做了太多的事或是变得臃肿,请将其拆成更小的组件并保持单一的原则。

5.Vue 组件命名

  • 有意义的: 不过于具体,也不过于抽象
  • 简短: 2 到 3 个单词
  • 具有可读性: 以便于沟通交流
<!-- 推荐 -->
<app-header></app-header>
<user-list></user-list>
<range-slider></range-slider><!-- 避免 -->
<btn-group></btn-group> <!-- 虽然简短但是可读性差. 使用 `button-group` 替代 -->
<ui-slider></ui-slider> <!-- ui 前缀太过于宽泛,在这里意义不明确 -->
<slider></slider> <!-- 与自定义元素规范不兼容 -->

6.验证组件的props

  • 提供默认值。
  • 使用 type 属性校验类型。
  • 使用 props 之前先检查该 prop 是否存在。
<template><input type="range" v-model="value" :max="max" :min="min">
</template>
<script type="text/javascript">export default {props: {max: {type: Number, // 这里添加了数字类型的校验default() { return 10; },},min: {type: Number,default() { return 0; },},value: {type: Number,default() { return 4; },},},};
</script>

7.只在需要时创建组件

Vue.js 是一个基于组件的框架。如果你不知道何时创建组件可能会导致以下问题:

  • 如果组件太大, 可能很难重用和维护;
  • 如果组件太小,你的项目就会(因为深层次的嵌套而)被淹没,也更难使组件间通信;

规则

  • 首先,尽可能早地尝试构建出诸如模态框、提示框、工具条、菜单、头部等这些明显的(通用型)组件。总之,你知道的这些组件以后一定会在当前页面或者是全局范围内需要。

  • 第二,在每一个新的开发项目中,对于一整个页面或者其中的一部分,在进行开发前先尝试思考一下。如果你认为它有一部分应该是一个组件,那么就创建它吧。

  • 最后,如果你不确定,那就不要。避免那些“以后可能会有用”的组件污染你的项目。它们可能会永远的只是(静静地)待在那里,这一点也不聪明。注意,一旦你意识到应该这么做,最好是就把它打破,以避免与项目的其他部分构成兼容性和复杂性。

注释规范

1.在vscode中使用vscode-fileheader插件,生成头部文件注释

2.普通的注释

2.1 总是在单行注释符后留一个空格

// this is comment

2.2 总是在多行注释的结束符前留一个空格(使星号对齐)

/* */

2.3 不要把注释写在多行注释的开始符、结束符所在行

// bad/* start end */// good
/* here is line 1 here is line 2 */

2.4 不要编写无意义的注释

// 初始化value变量为0
var value = 0;

2.5 如果某段代码有功能未实现,或者有待完善,必须添加“TODO”标记,“TODO”前后应留一个空格

// TODO 未处理IE6-8的兼容性
function setOpacity(node, val) {node.style.opacity = val;
}

3.文档注释

文档注释将会以预定格式出现在API文档中。它以“/”开头,以“/”结束,其间的每一行均以“”开头(均与开始符的第一个“”对齐),且注释内容与“”间留一个空格。

3.1 @module。声明模块

/** * 模块说明 * @module 模块名 *//** * Core模块提供最基础、最核心的接口 * @module Core */

3.2 @class。声明类

/** * 类说明 * @class 类名 * @constructor */

@class必须搭配@constructor或@static使用,分别标记非静态类与静态类。

/** * 节点集合类 * @class NodeList * @constructor * @param {ArrayLike<Element>} nodes 初始化节点 */

3.3 @method。声明函数或类方法

/** * 方法说明 * @method 方法名 * @for 所属类名 * @param {参数类型} 参数名 参数说明 * @return {返回值类型} 返回值说明 */

没有指定@for时,表示此函数为全局或模块顶层函数。当函数为静态函数时,必须添加@static;当函数有参数时,必须使用@param;当函数有返回值时,必须使用@return。

/** * 返回当前集合中指定位置的元素 * @method * @for NodeList * @param {Number} [i=0] 位置下标。如果为负数,则从集合的最后一个元素开始倒数 * @return {Element} 指定元素 */- @param。声明函数参数,必须与@method搭配使用。
- 当参数出现以下情况时,使用对应的格式:[参数名]
- 参数有默认值 [参数名 = 默认值]

3.4 @property。声明类属性

/** * 属性说明 * @property {属性类型} 属性名 */

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1n5nbfpbs3gam

转载于:https://my.oschina.net/u/2306318/blog/1609942

前端代码规范(es6,eslint,vue)相关推荐

  1. 前端代码规范工具ESLint和Prettier

    前端代码规范工具ESLint和Prettier 1. ESLint是什么? ESLint 是一个开源的 JavaScript 代码检查工具,由 Nicholas C. Zakas 于2013年6月创建 ...

  2. 技术胖前端代码规范秘籍推荐

    技术胖前端代码规范秘籍推荐 6个文档 ,一本书籍 ,2个工具 京东凹凸实验室前端代码规范 腾讯前端代码规范 百度前端代码规范 JavaScript Standard Style :是一个个人代码规范 ...

  3. 网站开发之前端代码规范

    前端代码规范 前言 一.唯一定律 二.前段代码规范 (一)命名规范 1.1.项目命名 1.2 .目录命名 1.3.文件存放位置 1.4.JS.CSS.HTML.PNG 等文件命名 1.4.命名严谨性 ...

  4. 前端代码规范参考和如何保持前端代码规范

    1.前端代码规范参考 编写前端代码规范的主要驱动力是两方面:  1) 代码一致性(一个项目的代码看起来就像一个人写的一样) 2) 最佳实践.  通过保持代码风格和传统的一致性,我们可以减少遗留系统维护 ...

  5. 前端代码规范网站推荐

    京东凹凸实验室前端代码规范 https://guide.aotu.io/ 链接 腾讯前端代码规范 链接http://tgideas.qq.com/doc/index.html 百度前端代码规范文档 链 ...

  6. 小团队的前端代码规范

    前端代码规范 文章目录 前端代码规范 1 前言 2 命名规范 1) 项目命名 2 )目录命名 3)`javaScript` 文件命名 4)`CSS`,`less`文件命名 5)HTML文件命名 6) ...

  7. 前端代码规范网址导航(总结)

    在大公司代码规范是非常重要的一件事情,多人协作,还有代码评审.所以能写出漂亮的代码非常重要. 这就好比你自己在家,无论是穿大裤衩子,还是背心,甚至是光膀子,都没人管你.但你要出门去约会,就要把最好的一 ...

  8. [Client]前端代码规范 及 最佳实践

    前端代码规范 及 最佳实践 2014/10/29 | 分类: WEB前端, 工具与资源, 开发 | 0 条评论 | 标签: 代码规范, 前端开发, 最佳实践 分享到: 62 本文作者: 伯乐在线 -  ...

  9. 【必看】前端代码规范

    代码规范 1. 概述 欢迎使用品优购代码规范, 这个是pink老师借鉴京东前端代码规范,组织的品优购内部规范(任何前端开发项目都适用的).旨在增强团队开发协作.提高代码质量和打造开发基石的编码规范, ...

最新文章

  1. python中isinstance(3、object)_Python中为什么推荐使用isinstance来进行类型判断?而不是type...
  2. mysql在linux下的安装_mysql在linux下的安装
  3. centos7安装yum_centos7下yum方式安装jenkins
  4. 特斯拉已在中国建立数据中心
  5. gamma分布_深度学习需要掌握的 13 个概率分布(含代码)
  6. 使用ipop共享串口提高工作效率
  7. 手机触摸pass测试软件,PASS——功效分析和样本量计算软件
  8. linux gif录制工具,教学?演示?在Linux下安装超好用的屏幕录像机来录制gif动画...
  9. 如何写好一篇英文科技论文
  10. Python多线程编程之线程子类化
  11. 安卓系统应用程序开发!灵魂一问-如何彻底防止APK反编译?大厂面试题汇总
  12. ESMTP协议与SMTP协议
  13. 用Canvas为网页添加动态背景
  14. 使用layui框架迅速搭建后台管理页面
  15. EV2400配合bqStudio的使用及电量计相关
  16. c#后端QQ通讯录(代码部分)
  17. AutoLayout技术选型和应用
  18. R/RStudio 常用函数
  19. 拳皇97 for Mac(街机格斗游戏)
  20. python杨辉三角 简单方法

热门文章

  1. python flask web开发_Python Flask web后端开发
  2. 声音匹配_如何调节人声音色方法如下
  3. kenrel volatile关键字
  4. UBUNTU 下查看所有的C库函数和查询 LINUX 编成必备
  5. 小米node2红外_使用python-miio控制小米智能插座
  6. 【资源分享】数字图像处理MATLAB版冈萨雷斯+中文高清版+随书源码链接
  7. 固态器件理论(2)价和晶体结构
  8. SAP Query达到select * where 的效果 2011-04-29
  9. 美国银行将 AI 应用于企业应收账款处理;联合国或将利用机器学习技术帮助救灾工作...
  10. MyEclipse-Web开发时何时重启tomcat、重新部署