Clean Code小結(jié)

  1. 使用有準(zhǔn)確意義的變量名

  2. 在變量值不會改變時使用const聲明一個常量

  3. 對同一類型的變量使用相同的詞匯

  4. 使用可搜索的名稱(用var聲明全局的大寫變量)

  5. 使用解釋型的變量

bad:

const cityStateRegex = /^(.+)[,\\s]+(.+?)\s*(\d{5})?$/;
saveCityState(cityStateRegex.match(cityStateRegex)[1], cityStateRegex.match(cityStateRegex)[2]);

good:

const cityStateRegex = /^(.+)[,\\s]+(.+?)\s*(\d{5})?$/;
const match = cityStateRegex.match(cityStateRegex)
const city = match[1];
const state = match[2];
saveCityState(city, state);
  1. 短路語法比條件語句更清晰
  2. 函數(shù)參數(shù)理論上少于等于2個
  3. 一個函數(shù)只做一件事
  4. 函數(shù)名稱要說明他做的事
  5. 函數(shù)應(yīng)該只抽象一個層次
  6. 刪除重復(fù)代碼
  7. 使用默認(rèn)參數(shù)代替短路表達(dá)式

bad:

function writeForumComment(subject, body) {
  subject = subject || 'No Subject';
  body = body || 'No text';
}

good:

function writeForumComment(subject = 'No subject', body = 'No text') {
  ...
}
  1. 用Object.assign設(shè)置默認(rèn)對象
config = Object.assign({
    title: 'Foo',
    body: 'Bar',
    buttonText: 'Baz',
    cancellable: true
  }, config);
  1. 不要把標(biāo)記用作函數(shù)參數(shù)(Boolean值)

bad:

function createFile(name, temp) {
  if (temp) {
    fs.create('./temp/' + name);
  } else {
    fs.create(name);
  }
}

good:

function createTempFile(name) {
  fs.create('./temp/' + name);
}

function createFile(name) {
  fs.create(name);
}
  1. 避免否定條件
  2. 封裝條件

bad:

if (fsm.state === 'fetching' && isEmpty(listNode)) {
  /// ...
}

good:

function shouldShowSpinner(fsm, listNode) {
  return fsm.state === 'fetching' && isEmpty(listNode);
}

if (shouldShowSpinner(fsmInstance, listNodeInstance)) {
  // ...
}
  1. 避免副作用

函數(shù)參數(shù)名和全局變量一樣時,將全局變量置于函數(shù)之后

  1. 喜歡上命令式編程之上的函數(shù)式編程

bad:

const programmerOutput = [
  {
    name: 'Uncle Bobby',
    linesOfCode: 500
  }, {
    name: 'Suzie Q',
    linesOfCode: 1500
  }, {
    name: 'Jimmy Gosling',
    linesOfCode: 150
  }, {
    name: 'Gracie Hopper',
    linesOfCode: 1000
  }
];

var totalOutput = 0;

for (var i = 0; i < programmerOutput.length; i++) {
  totalOutput += programmerOutput[i].linesOfCode;
}

good:

const programmerOutput = [
  {
    name: 'Uncle Bobby',
    linesOfCode: 500
  }, {
    name: 'Suzie Q',
    linesOfCode: 1500
  }, {
    name: 'Jimmy Gosling',
    linesOfCode: 150
  }, {
    name: 'Gracie Hopper',
    linesOfCode: 1000
  }
];

var totalOutput = programmerOutput
  .map((programmer) => programmer.linesOfCode)
  .reduce((acc, linesOfCode) => acc + linesOfCode, 0);
  1. 避免條件
  2. 避免類型檢查
  3. 不要過度優(yōu)化

bad:

for (var i = 0, len = list.length; i < len; i++) {
  // ...
}

good:

for (var i = 0; i < list.length; i++) {
  // ...
}
  1. 刪除不用的代碼(不要注釋代碼)
  2. 使用getter和setter

bad:

class BankAccount {
  constructor() {
       this.balance = 1000;
  }
}

let bankAccount = new BankAccount();

// 支出
bankAccount.balance = bankAccount.balance - 100;

good:

class BankAccount {
  constructor() {
       this.balance = 1000;
  }

  // It doesn't have to be prefixed with `get` or `set` to be a getter/setter
  withdraw(amount) {
    if (verifyAmountCanBeDeducted(amount)) {
      this.balance -= amount;
    }
  }
}

let bankAccount = new BankAccount();

bankAccount.withdraw(100);

  1. 讓對象擁有私有成員(通過函數(shù)return)

bad:

var Employee = function(name) {
  this.name = name;
}

Employee.prototype.getName = function() {
  return this.name;
}

var employee = new Employee('John Doe');
console.log('Employee name: ' + employee.getName()); // Employee name: John Doe
delete employee.name;
console.log('Employee name: ' + employee.getName()); // Employee name: undefined

good:

var Employee = (function() {
  function Employee(name) {
    this.getName = function() {
      return name;
    };
  }

  return Employee;
}());

var employee = new Employee('John Doe');
console.log('Employee name: ' + employee.getName()); // Employee name: John Doe
delete employee.name;
console.log('Employee name: ' + employee.getName()); // Employee name: John Doe
  1. 類-單一職責(zé)原則(SRP)
  2. 開放封裝原則(OCP)
  3. 里氏替換原則(LSP)
  4. 接口隔離原則(ISP)
  5. 依賴倒置原則(DIP)
  6. async/await

bad:(promise)

require('request-promise').get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin')
  .then(function(response) {
    return require('fs-promise').writeFile('article.html', response);
  })
  .then(function() {
    console.log('File written');
  })
  .catch(function(err) {
    console.error(err);
  })

good:

async function getCleanCodeArticle() {
  try {
    var request = await require('request-promise')
    var response = await request.get('https://en.wikipedia.org/wiki/Robert_Cecil_Martin');
    var fileHandle = await require('fs-promise');

    await fileHandle.writeFile('article.html', response);
    console.log('File written');
  } catch(err) {
      console.log(err);
    }
  }
  1. 錯誤處理
try {
  functionThatMightThrow();
} catch (error) {
  // 選擇之一(比 console.log 更鬧心):
  console.error(error);
  // 另一個選擇:
  notifyUserOfError(error);
  // 另一個選擇:
  reportErrorToService(error);
  // 或者所有上述三種選擇庆揪!
}

  1. 使用一致的大小寫
  2. 調(diào)用者和被調(diào)用者盡可能的放在一起
  3. 刪除已注釋代碼及盡量少使用注釋
  4. 做有意義的區(qū)分,依義命名

不要使用如a1斤蔓,a2猎唁,a3...這樣沒有區(qū)分度的命名,用parent,children等有意義的區(qū)分

  1. 不要使用雙關(guān)語

如add监氢,使用append或insert這類動詞

  1. 變量,函數(shù)藤违,類的命名應(yīng)該盡量簡短浪腐,有具體意義(data,info都是一個意思)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末顿乒,一起剝皮案震驚了整個濱河市议街,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌璧榄,老刑警劉巖特漩,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吧雹,死亡現(xiàn)場離奇詭異,居然都是意外死亡涂身,警方通過查閱死者的電腦和手機雄卷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蛤售,“玉大人丁鹉,你說我怎么就攤上這事°材埽” “怎么了揣钦?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長漠酿。 經(jīng)常有香客問我冯凹,道長,這世上最難降的妖魔是什么记靡? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任谈竿,我火速辦了婚禮,結(jié)果婚禮上摸吠,老公的妹妹穿的比我還像新娘空凸。我一直安慰自己,他們只是感情好寸痢,可當(dāng)我...
    茶點故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布呀洲。 她就那樣靜靜地躺著,像睡著了一般啼止。 火紅的嫁衣襯著肌膚如雪道逗。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天献烦,我揣著相機與錄音滓窍,去河邊找鬼。 笑死巩那,一個胖子當(dāng)著我的面吹牛吏夯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播即横,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼噪生,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了东囚?” 一聲冷哼從身側(cè)響起跺嗽,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后桨嫁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體植兰,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年瞧甩,在試婚紗的時候發(fā)現(xiàn)自己被綠了钉跷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡肚逸,死狀恐怖爷辙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情朦促,我是刑警寧澤膝晾,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站务冕,受9級特大地震影響血当,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜禀忆,卻給世界環(huán)境...
    茶點故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一臊旭、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧箩退,春花似錦离熏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至啥刻,卻和暖如春奸鸯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背可帽。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工娄涩, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人映跟。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓钝满,卻偏偏與公主長得像,于是被迫代替她去往敵國和親申窘。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容