天天看點

前端代碼規範(es6,eslint,vue)前端開發規範

前端開發規範

一、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>           
前端代碼規範(es6,eslint,vue)前端開發規範
前端代碼規範(es6,eslint,vue)前端開發規範

請確定正确使用語義化的标簽,錯誤的用法甚至不如保守的用法。

<!-- 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 [email protected] 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 [email protected] 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) { ... }    //  avoid

run(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 err
  window.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 () { }     //  ok

var 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) {    //  avoid
    this.name = value
  }
}
var person = {
  set name (value) {
    this.name = value
  },
  get name () {         //  ok
    return 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) return

  arguments.callee(n - 1)   //  avoid
}

function foo (n) {
  if (n <= 0) return

  foo(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      //  avoid
  return 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'          //  avoid

import { 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)    //  avoid

const 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()    //  avoid
  case 2:
    doSomethingElse()
}

switch (filter) {
  case 1:
    doSomething()
    break           //  ok
  case 2:
    doSomethingElse()
}

switch (filter) {
  case 1:
    doSomething()
    // fallthrough //  ok
  case 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 () {
  {                   //  avoid
    myOtherFunc()
  }
}

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'     //  avoid

let name = 'John'
name = 'Jane'         //  ok
76.正則中避免使用多個空格。
eslint: no-regex-spaces
const regexp = /test value/   //  avoid

const 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     //  avoid
    super()
  }
}
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    //  avoid

let 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 true
  console.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' }    //  ok

const user = {
  name: 'Jane Doe',
  age: 30,
  username: 'jdoe86'
}
102.代碼塊中避免多餘留白。
eslint: padded-blocks
if (user) {
                            //  avoid
  const 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 () { }()     //  avoid

const 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]           

es6文法規範

1.let 取代 var

ES6 提出了兩個新的聲明變量的指令:let和const。其中,let完全可以取代var,因為兩者語義相同,而且let沒有副作用。

2.全局常量const

在全局環境,不應該設定變量,隻應設定常量

好處:

const

優于

let

有幾個原因。一個是

const

可以提醒閱讀程式的人,這個變量不應該改變;另一個是

const

比較符合函數式程式設計思想,運算不改變值,隻是建立值,而且這樣也有利于将來的分布式運算;最後一個原因是 JavaScript 編譯器會對

const

進行優化,是以多使用

const

,有利于提高程式的運作效率,也就是說

let

const

的本質差別,其實是編譯器内部的處理不同。 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 {屬性類型} 屬性名 */           

原文釋出時間為:2018年01月20日

原文作者:

放開那個女孩

本文來源:

開源中國

如需轉載請聯系原作者

繼續閱讀