(1)變量數量的定義javascript
NO:濫用變量vue
let kpi = 4; // 定義好了以後再也沒用過 function example() { var a = 1; var b = 2; var c = a+b; var d = c+1; var e = d+a; return e; }
YES: 數據只使用一次或不使用就無需裝到變量中java
let kpi = 4; // 沒用的就刪除掉,否則過三個月本身都不敢刪,怕是否是那用到了 function example() { var a = 1; var b = 2; return 2a+b+1; }
(2)變量的命名程序員
NO:自我感受良好的縮寫vuex
let fName = 'jackie'; // 看起來命名挺規範,縮寫,駝峯法都用上,ESlint各類檢測規範的工具都經過,But,fName是啥?這時候,你是否是想說What are you 弄啥呢? let lName = 'willen'; // 這個問題和上面的同樣
YES: 無需對每一個變量都寫註釋,從名字上就看懂編程
let kpi = 4; // 沒用的就刪除掉,否則過三個月本身都不敢刪,怕是否是那用到了 let firstName = 'jackie'; // 怎麼樣,是否是一目瞭然。少被噴了一次 let lastName = 'willen';
(3)特定的變量redux
NO:無說明的參數api
if (value.length < 8) { // 爲何要小於8,8表示啥?長度,仍是位移,仍是高度?Oh,my God!! .... }
YES: 添加變量數組
const MAX_INPUT_LENGTH = 8; if (value.length < MAX_INPUT_LENGTH) { // 一目瞭然,不能超過最大輸入長度 .... }
(4)變量的命名函數
NO:命名過於囉嗦
let nameString; let theUsers; }
YES: 作到簡潔明瞭
let name; let users;
(5)使用說明性的變量(即有意義的變量名)
NO:長代碼不知道啥意思
const address = 'One Infinite Loop, Cupertino 95014'; const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; saveCityZipCode( address.match(cityZipCodeRegex)[1], // 這個公式到底要幹嗎,對不起,原做者已經離職了。本身看代碼 address.match(cityZipCodeRegex)[2], // 這個公式到底要幹嗎,對不起,原做者已經離職了。本身看代碼 );
YES: 用變量名來解釋長代碼的含義
const address = 'One Infinite Loop, Cupertino 95014'; const cityZipCodeRegex = /^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/; const [, city, zipCode] = address.match(cityZipCodeRegex) || []; saveCityZipCode(city, zipCode);
(6)避免使用太多的全局變量
NO:在不一樣的文件不停的定義全局變量
name.js window.name = 'a'; hello.js window.name = 'b'; time.js window.name = 'c'; //三個文件的前後加載順序不一樣,都會使得window.name的值不一樣,同時,你對window.name的修改了都有可能不生效,由於你不知道你修改過以後別人是否是又在別的說明文件中對其的值重置了。因此隨着文件的增多,會致使一團亂麻。
YES: 少用或使用替代方案
你能夠選擇只用局部變量。經過(){}的方法。 若是你確實用不少的全局變量須要共享,你可使用vuex,redux或者你本身參考flux模式寫一個也行。
(7)變量的賦值
NO:對於求值獲取的變量,沒有兜底
const MIN_NAME_LENGTH = 8; let lastName = fullName[1]; if(lastName.length > MIN_NAME_LENGTH) { // 這樣你就給你的代碼成功的埋了一個坑,你有考慮過若是fullName = ['jackie']這樣的狀況嗎?這樣程序一跑起來就爆炸。要不你試試。 .... }
YES: 對於求值變量,作好兜底
const MIN_NAME_LENGTH = 8; let lastName = fullName[1] || ''; // 作好兜底,fullName[1]中取不到的時候,不至於賦值個undefined,至少還有個空字符,從根本上講,lastName的變量類型仍是String,String原型鏈上的特性都能使用,不會報錯。不會變成undefined。 if(lastName.length > MIN_NAME_LENGTH) { .... } 其實在項目中有不少求值變量,對於每一個求值變量都須要作好兜底。 let propertyValue = Object.attr || 0; // 由於Object.attr有可能爲空,因此須要兜底。 可是,賦值變量就不須要兜底了。 let a = 2; // 由於有底了,因此不要兜着。 let myName = 'Tiny'; // 由於有底了,因此不要兜着。
(1)函數命名
NO:從命名沒法知道返回值類型
function showFriendsList() {....} // 如今問,你知道這個返回的是一個數組,仍是一個對象,仍是true or false。你能答的上來否?你能答得上來我請你吃松鶴樓的滿漢全席還請你不要當真。 );
YES: 對於返回true or false的函數,最好以should/is/can/has開頭
function shouldShowFriendsList() {...} function isEmpty() {...} function canCreateDocuments() {...} function hasLicense() {...}
(2)功能函數最好爲純函數
NO:不要讓功能函數的輸出變化無常
function plusAbc(a, b, c) { // 這個函數的輸出將變化無常,由於api返回的值一旦改變,一樣輸入函數的a,b,c的值,但函數返回的結果卻不必定相同。 var c = fetch('../api'); return a+b+c; }
YES: 功能函數使用純函數,輸入一致,輸出結果永遠惟一
function plusAbc(a, b, c) { // 一樣輸入函數的a,b,c的值,但函數返回的結果永遠相同。 return a+b+c; }
(3)函數傳參
NO:傳參無說明
page.getSVG(api, true, false); // true和false啥意思,一目不了然
YES: 傳參有說明
page.getSVG({ imageApi: api, includePageBackground: true, // 一目瞭然,知道這些true和false是啥意思 compress: false, })
(4)動做函數要以動詞開頭
NO:沒法辨別函數意圖
function emlU(user) { .... }
YES: 動詞開頭,函數意圖就很明顯
function sendEmailToUser(user) { .... }
(5)一個函數完成一個獨立的功能,不要一個函數混雜多個功能
NO:函數功能混亂,一個函數包含多個功能。最後就像能以一當百的老師傅同樣,被亂拳打死(亂拳(功能複雜函數)打死老師傅(老程序員))
function sendEmailToClients(clients) { clients.forEach(client => { const clientRecord = database.lookup(client) if (clientRecord.isActive()) { email(client) } }) }
YES: 功能拆解
function sendEmailToActiveClients(clients) { //各個擊破,易於維護和複用 clients.filter(isActiveClient).forEach(email) } function isActiveClient(client) { const clientRecord = database.lookup(client) return clientRecord.isActive() }
(6)優先使用命令式編程
NO:使用for循環編程
for(i = 1; i <= 10; i++) { // 一看到for循環讓人頓生不想看的情愫 a[i] = a[i] +1; }
YES: 使用命令式編程
let b = a.map(item => ++item) // 怎麼樣,是否是很好理解,就是把a的值每項加一賦值給b就能夠了。如今在javascript中幾乎全部的for循環均可以被map,filter,find,some,any,forEach等命令式編成取代。
(7)函數中過多的採用if else
NO: if else過多
if (a === 1) { ... } else if (a ===2) { ... } else if (a === 3) { ... } else { ... }
YES: 可使用switch替代或用數組替代
switch(a) { case 1: .... case 2: .... case 3: .... default: .... } Or let handler = { 1: () => {....}, 2: () => {....}. 3: () => {....}, default: () => {....} } handler[a]() || handler['default']()
(只羅列最經常使用的新語法,說實話,有些新語法不怎麼經常使用)
(1)儘可能使用箭頭函數
NO:採用傳統函數
function foo() { // code }
YES: 使用箭頭函數
let foo = () => { // code }
(2)鏈接字符串
NO:採用傳統+號
var message = 'Hello ' + name + ', it\'s ' + time + ' now'
YES: 採用模板字符
var message = `Hello ${name}, it's ${time} now`
(3)使用解構賦值
NO:使用傳統賦值
var data = { name: 'dys', age: 1 }; var name = data.name; var age = data.age; var fullName = ['jackie', 'willen']; var firstName = fullName[0]; var lastName = fullName[1];
YES: 使用結構賦值
const data = {name:'dys', age:1}; const {name, age} = data; // 怎麼樣,是否是簡單明瞭 var fullName = ['jackie', 'willen']; const [firstName, lastName] = fullName;
(4) 儘可能使用類class
NO:採用傳統的函數原型鏈實現繼承
典型的 ES5 的類(function)在繼承、構造和方法定義方面可讀性較差,當須要繼承時,優先選用 class。代碼太多,就省略了。
*YES: 採用ES6類實現繼承
class Animal { constructor(age) { this.age = age } move() { /* ... */ } } class Mammal extends Animal { constructor(age, furColor) { super(age) this.furColor = furColor } liveBirth() { /* ... */ } } class Human extends Mammal { constructor(age, furColor, languageSpoken) { super(age, furColor) this.languageSpoken = languageSpoken } speak() { /* ... */ } }
先寫到這了,後續有再補上…
來源:https://blog.csdn.net/qq_36436877/article/details/85158050