論如何優雅的寫出不會捱揍的代碼

參照github明星項目之一 `nocode`,給出如下建議。
複製代碼

No Code

No code is the best way to write secure and reliable applications. Write nothing; deploy nowhere.javascript

Getting Started

Start by not writing any code.html

複製代碼

This is just an example application, but imagine it doing anything you want. Adding new features is easy too:前端

複製代碼

The possibilities are endless.java

Building the Application

Now that you have not done anything it's time to build your application:git

複製代碼

Yep. That's it. You should see the following output:github

複製代碼

Deploying

While you still have not done anything it's time to deploy your application. By running the following command you can deploy your application absolutely nowhere.數據庫

複製代碼

你會不會被同事打死我不知道,但你會被老闆打死這是確定的。 編程

好了,上面只是開個玩笑,在這裏附上nocode的地址,你們有空能夠瞻仰一下。json

如今進入正題。不少時候咱們會遇到修改其餘人的代碼或在對方代碼上添加功能的狀況,我想大部分人當時內心必定是這樣的。後端


那如何儘量的保全本身呢?

  1. 謝同事不殺之恩,平時多投喂些零食。
  2. 寫出好代碼。

我我的但願你能靜下心來仔細的品一遍,若是你有收穫,請給做者點個贊吧,讓我知道還有人從這裏得到了知識。雖然很瑣碎,也可能你會浪費人生中寶貴的八分鐘。

向盟約宣誓~~~~

語言規範

引用

const 和 let 都是塊級做用域,var 是函數級做用域

  • 對全部不可變引用都使用 const,可變引用使用let,不要使用 var
// bad
var a = 1
var b = 2
if (b < 10) {
  b += 1
}

// good
const a = 1
let b = 2
if (count < 10) {
  count += 1
}
複製代碼
  • 鏈式賦值 鏈式賦值容易形成代碼的可讀性差,約定禁止使用鏈式賦值
不推薦

let a = b = c = 1
推薦

let a = 1
let b = 1
let c = 1
複製代碼

對象

  • 請使用字面量值建立對象
// bad
const a = new Object{}

// good
const a = {}
複製代碼
  • 請使用對象屬性值的簡寫方式
  • 對象屬性的每一行末尾添加·逗號·,詳見下方 拖尾逗號
  • 變量的聲明後追加分號,若遵循 Standard 的規範,忽略本條。
  • 如已有統一規範,請忽略上述兩條。
const job = 'FrontEnd';

// bad
const item = {
  job: job
}

// good
const item = {
  job,
};
複製代碼

你永遠不能保證這個對象會不會被追加屬性,因此熱情的幫你的同事補上每行的·逗號·吧~
不然若是你同事恰好開啓了代碼檢查,他極可能會來揍你

數組

  • 使用字面量值建立數組
  • 向數組中添加元素時,請使用 push 方法
// bad
const items = new Array();
items[items.length] = 'test';


// good
const items = [];
items.push('test');

複製代碼
  • 使用拓展運算符 ... 複製數組
const items = [];
const itemsCopy = [];
const len = items.length;
let i;

// bad
for (i = 0; i < len; i++) {
  itemsCopy[i] = items[i];
}

// good
itemsCopy = [...items];
複製代碼

嗯。。。我以爲如今應該見不到bad方式的寫法了吧。。大概?

  • 使用forEach、some、every等代替for循環
const items = [];
const len = items.length;

// bad
for (i = 0; i < len; i++) {
 // todo something for items[i]
}

// good
items.forEach((item, index) => {
    // todo something for items
});
複製代碼
  • 使用數組的 map方法時,請使用 return 聲明,若是是單一聲明語句的狀況,可省略 return
// good
[1, 2, 3].map(x => {
  const y = x + 1
  return x * y
});

// good
[1, 2, 3].map(x => x + 1);
複製代碼
  • 使用數組的 reduce方法時,請賦予初值,並使用 return 聲明,若是是單一聲明語句的狀況,可省略 return
// good
const flat = [[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => {
  const flatten = memo.concat(item)
  return flatten
}, []);
複製代碼

我知道在座的都是大佬,但萬一其中混入了奇怪的東西呢?

  • 使用數組的 filter方法時,使用單一判斷,保證最後總會返回false/true
// bad
inbox.filter((msg) => {
  const { subject, author } = msg
  if (subject === 'Mockingbird') {
    return author === 'Harper Lee'
  } else {
    return false
  }
})

// good
inbox.filter((msg) => {
  const { subject, author } = msg
  if (subject === 'Mockingbird') {
    return author === 'Harper Lee'
  }
  return false
})
複製代碼

解構賦值

  • 當須要使用對象的多個屬性時,請使用解構賦值
// bad
function getFullName (user) {
  const firstName = user.firstName
  const lastName = user.lastName

  return `${firstName} ${lastName}`
}

// good
function getFullName (user) {
  const { firstName, lastName } = user

  return `${firstName} ${lastName}`
}

// better
function getFullName ({ firstName, lastName }) {
  return `${firstName} ${lastName}`
}
複製代碼
  • 當須要使用數組的多個值時,請一樣使用解構賦值
const arr = [1, 2, 3, 4]

// bad
const first = arr[0]
const second = arr[1]

// good
const [first, second] = arr
複製代碼
  • 函數須要回傳多個值時,請使用對象的解構,而不是數組的解構
// bad
function doSomething () {
  return [top, right, bottom, left]
}

// 若是是數組解構,那麼在調用時就須要考慮數據的順序
const [top, xx, xxx, left] = doSomething()

// good
function doSomething () {
  return { top, right, bottom, left }
}

// 此時不須要考慮數據的順序
const { top, left } = doSomething()
複製代碼

經典狀況:

// 在使用callback形式的時候,我常常會想,我定義的第一個參數是err仍是data。。。
function handle(){
    // todo something
    if(err){
        return [null,err];
    }
    // todo something
    return [data,err];
}

function handle1(){
    // todo something
    if(err){
        return [err,null];
    }
    // todo something
    return [err,data];
}
複製代碼

字符串

  • 字符串統一使用單引號的形式 ''
// bad
const department = "JDC"

// good
const department = 'JDC'
複製代碼
  • 字符串太長的時候,請不要使用字符串鏈接符換行 \,而是使用 +
const str = '一鍵三連~' +
  '鍵三連~ 三連~ ' +
  '連~'
複製代碼
  • 程序化生成字符串時,請使用模板字符串
const test = 'test'

// bad
const str = ['a', 'b', test].join()

// bad
const str = 'a' + 'b' + test

// good
const str = `ab${test}`
複製代碼
  • 讀取字符串中的字符時使用標準方法
// 優先使用 
string.charAt(3) 

// 而不是 
string[3]
複製代碼

函數

  • 不要使用 arguments,能夠選擇使用 ...

arguments 只是一個類數組,而 ... 是一個真正的數組

// good
function test (...args) {
  return args.join('')
}
複製代碼
  • 不要更改函數參數的值
// bad
function test (opts) {
  opts = opts || {}
}
// bad
function test1 (opts) {
  if(!ops){
      ops = {};
  }
}

// good
function test (opts = {}) {
  // ...
}
複製代碼

編碼規範

單行代碼塊

  • 在單行代碼塊中使用空格
// 不推薦
function foo () {return true}
if (foo) {bar = 0}

// 推薦
function foo () { return true }
if (foo) { bar = 0 }
複製代碼

大括號兩側都要有空格,但每行末尾不要有空格
我的不推薦單行代碼塊,由於總會碰到向裏面追加語句狀況

大括號風格

在編程過程當中,大括號風格與縮進風格緊密聯繫,用來描述大括號相對代碼塊位置的方法有不少。在 JavaScript 中,主要有三種風格,以下:

// One True Brace Style
if (foo) {
  bar()
} else {
  baz()
}

// Stroustrup
if (foo) {
  bar()
}
else {
  baz()
}

// Allman
if (foo)
{
  bar()
}
else
{
  baz()
}
複製代碼

建議使用第一種風格,請注意大括號兩側的空格,行頭及末尾不添加空格

變量命名

當命名變量時,主流分爲駝峯式命名(variableName)和下劃線命名(variable_name)兩大陣營。

約定變量及形參使用駝峯式命名
由於涉及後端開發,補充約定數據庫參數使用下劃線命名

逗號

  • 拖尾逗號
    在 ECMAScript5 裏面,對象字面量中的拖尾逗號是合法的,但在 IE8(非 IE8 文檔模式)下,當出現拖尾逗號,則會拋出錯誤。

拖尾逗號的例子:

var foo = {
  name: 'foo',
  age: '22',
}
複製代碼

拖尾逗號的好處是,簡化了對象和數組添加或刪除元素,咱們只須要修改新增的行便可,並不會增長差別化的代碼行數。

約定在最後一個元素或屬性與閉括號 ] 或 } 在不一樣行時, 建議使用拖尾逗號。
當在同一行時,禁止使用拖尾逗號。

  • 逗號空格

逗號先後的空格能夠提升代碼的可讀性,團隊約定在逗號後面使用空格,逗號前面不加空格。

// 不推薦
var foo = 1,bar = 2
var foo = 1 , bar = 2
var foo = 1 ,bar = 2

// 推薦
var foo = 1, bar = 2
複製代碼

逗號請務必放在當前行

計算屬性的空格

在對象的計算屬性內,禁止使用空格

當屬性名不帶中劃線等須要特別處理的字符串時,推薦直接使用obj.foo

// 不推薦
obj['foo' ]
obj[ 'foo']
obj[ 'foo' ]

// 推薦
obj['foo']
複製代碼

拖尾換行

在非空文件中,存在拖尾換行是一個常見的 UNIX 風格,它的好處是能夠方便在串聯和追加文件時不會打斷 Shell 的提示。在平常的項目中,保留拖尾換行的好處是,能夠減小版本控制時的代碼衝突。

不推薦

function func () {
  // do something
}
推薦

function func () {
  // do something
}
  // 此處是新的一行
複製代碼

即每一個文件的最後都包含一個空行

縮進

代碼保持一致的縮進,是做爲工程師的職業素養,也是減小合併衝突的保證
約定使用 空格 來縮進,並且縮進使用兩個空格。

可經過設置IDE將tab設置爲2空格

對象字面量的鍵值縮進

約定對象字面量的冒號和值之間存在一個空格

// 不推薦
var obj = { 'foo' : 'haha' }

// 推薦
var obj = { 'foo': 'haha' }
複製代碼

操做符的空格

約定操做符先後都須要添加空格

// 不推薦
var sum = 1+2

// 推薦
var sum = 1 + 2
複製代碼

構造函數首字母大寫

約定構造函數的首字母要大寫,以此來區分構造函數和普通函數。

類名大寫也是必定的了~

// 不推薦
var fooItem = new foo()

// 推薦
var fooItem = new Foo()
複製代碼

空行

空白行對於分離代碼邏輯有幫助,但過多的空行會佔據屏幕的空間,影響可讀性。

  • 約定最大連續空行數爲 2
  • 約定函數內部首行不爲空行
  • 約定函數間使用空行隔離

空格

  1. 除了每行的開頭及末尾,代碼塊大括號兩側都應有空格

function foo () { return true } if (foo) {
  bar()
} else {
  baz()
}

  1. 操做符先後都添加空格

const sum = 1 + 2

  1. 逗號和冒號後面增長空格

const cat = { name: nico, color: 'white' }

  1. 行級註釋// 先後添加空格

const a = 1; // 定義變量a

風格規範

好的編程風格是能夠直接影響同事的感官的

註釋

必定要寫註釋!
必定要寫註釋!
必定要寫註釋!

無論你用什麼框架,使用什麼ide,是否使用ts,請記住:

  • 文件、類、函數註釋必須使用 JSDoc規範,使用/*內容/格式,不得使用 // xxx方式。
  • 方法內部單行註釋,在被註釋語句上方另起一行,使用//註釋。
  • 全部的枚舉類型字段必需要有註釋,說明每一個數據項的用途。
  • 與其「半吊子」英文來註釋,不如用中文註釋把問題說清楚
  • 好的命名、代碼結構是自解釋的,不使用無心義的註釋

無論有多忙,請必定寫上註釋,不然過幾個月連你本身都不知道本身怎麼想的了。。。

/**
 * 處理全部關於數值計算的問題
 * 
 * @author XXX
 */
 
/**
 * 求和函數
 * @param { number } a 
 * @param { number} b
 * @returns {number} sum
 */
function sun(a, b) {
  return a + b;
}

複製代碼

抽取功能函數

  • 單一功能儘量抽取功能函數
    • 頁面加載時請求的不一樣類型數據的操做分別抽取成函數 -> 保證每一個請求能夠靈活修改邏輯
    • 頁面銷燬時須要設置的狀態操做抽取成函數,-> 能夠保證有統一的入口,防止遺漏某些操做
    • 控制組件狀態的操做抽取成函數 -> 方便在流程中作攔截以及追加操做
  • 不要在框架任何一個生命週期函數中直接寫大量語句 -> 這樣真的會被揍
  • 把可能變化的地方封裝成函數 -> 需求老是變化的,你懂的
  • 數據結構上要考慮功能未來的擴展 -> 同上

條件語句

  • 條件語句必須添加大括號
// bad
function test (opts) {
  if(opts.length > 0)
    // todo something
  // todo other
}


// good
function test (opts) {
  if(opts.length > 0) {
      // todo something
  }
  // todo other
}
複製代碼

定義工具類

定義本身的工具類, 儘可能不要在業務代碼裏面直接調用第三方的工具類
如:

  • 字符串處理: 判斷字符串是否符合規範
  • 判斷是不是json對象

提示: 請寫好註釋,並告訴你們你的函數,不然 -> 跟沒寫差很少

謹慎註釋掉代碼。

  • 在上方詳細說明,而不是簡單地註釋掉。
  • 廢棄方法或廢棄文件務必添加註釋或刪除

有時候會碰到改了半天代碼結果bug毫無變化,而後驚喜的發現此方法已廢棄。。。

最後,推薦方法三: ts/eslint開啓上線前檢查,不經過一概pass

請在新項目中使用,不然你會揍你本身


以上,酌情遵照,最重要的是你們開開心心的寫代碼就好

後續遇到新的想罵人的地方會補充上,請給我一鍵三連吧~~~

相關係列: 從零開始的前端築基之旅(超級精細,持續更新~)

參考文檔:
guide.aotu.io/docs/js/cod… 阿里巴巴Java開發手冊

相關文章
相關標籤/搜索