本篇匯總了平時(shí)在工作開發(fā)中常遇到的業(yè)務(wù)邏輯的優(yōu)雅寫法,也匯總了自己還是新人時(shí),拿到一個(gè)業(yè)務(wù)不知道怎么下手的痛點(diǎn),依稀記得那時(shí)候總感覺自己寫的代碼不規(guī)范。
寫完之后,感覺還是美好的,又學(xué)到東西了。
正文開始
為什么要寫一手優(yōu)雅的代碼?
采用簡(jiǎn)潔的語法和結(jié)構(gòu),遵循一致的命名規(guī)范,具有良好的代碼組織和注釋,同時(shí)表達(dá)了代碼的意圖和邏輯。
主要有以下幾個(gè)優(yōu)點(diǎn):
-
可讀性:易于閱讀和理解。清晰的命名、簡(jiǎn)潔的語法和良好的代碼結(jié)構(gòu)可以使代碼的意圖更加明確,
降低理解代碼的難度
,提高代碼的可讀性。 -
可維護(hù)性:易于維護(hù)。當(dāng)代碼邏輯清晰、結(jié)構(gòu)簡(jiǎn)潔時(shí),開發(fā)者可以
更快速地定位和修復(fù)bug
,進(jìn)行功能擴(kuò)展或修改。同時(shí),可讀性高的代碼也有助于后續(xù)的代碼重構(gòu)和優(yōu)化。 -
可擴(kuò)展性:更具有擴(kuò)展性和
靈活性
。清晰的代碼結(jié)構(gòu)和簡(jiǎn)潔的代碼風(fēng)格使得添加新功能、修改現(xiàn)有功能或擴(kuò)展代碼更加容易。此外,簡(jiǎn)潔的代碼往往更少依賴于特定的實(shí)現(xiàn)細(xì)節(jié),提供了更多的靈活性和可替換性。 -
錯(cuò)誤減少和調(diào)試時(shí)間:
更容易寫出正確的邏輯,減少了出錯(cuò)的概率
。同時(shí),當(dāng)代碼出現(xiàn)問題時(shí),優(yōu)雅簡(jiǎn)潔的代碼也更容易進(jìn)行調(diào)試和定位錯(cuò)誤。 -
性能優(yōu)化:簡(jiǎn)潔的代碼通常更高效,減少了不必要的計(jì)算和資源消耗。精簡(jiǎn)的代碼結(jié)構(gòu)和算法可以提高代碼的執(zhí)行效率和性能
基本功
1. 使用箭頭函數(shù)簡(jiǎn)化函數(shù)定義
//?傳統(tǒng)函數(shù)定義
function?add(a,?b)?{
?return?a?+?b;
?}
??
?//?箭頭函數(shù)簡(jiǎn)化
?const?add?=?(a,?b)?=>?a?+?b;
2. 使用解構(gòu)賦值簡(jiǎn)化變量聲明
//?傳統(tǒng)變量聲明
const?firstName?=?person.firstName;
const?lastName?=?person.lastName;
//?解構(gòu)賦值簡(jiǎn)化
const?{?firstName,?lastName?}?=?person;
3. 使用模板字面量進(jìn)行字符串拼接
//?傳統(tǒng)字符串拼接
const?greeting?=?'Hello,?'?+?name?+?'!';
//?模板字面量簡(jiǎn)化
const?greeting?=?`Hello,?${name}!`;
4. 使用展開運(yùn)算符進(jìn)行數(shù)組和對(duì)象操作
//?合并數(shù)組
const?combined?=?[...array1,?...array2];
//?復(fù)制對(duì)象
const?clone?=?{?...original?};
5. 使用數(shù)組的高階方法簡(jiǎn)化循環(huán)和數(shù)據(jù)操作
//?遍歷數(shù)組并返回新數(shù)組
const?doubled?=?numbers.map(num?=>?num?*?2);
//?過濾數(shù)組
const?evens?=?numbers.filter(num?=>?num?%?2?===?0);
6. 使用條件運(yùn)算符簡(jiǎn)化條件判斷
//?傳統(tǒng)條件判斷
let?message;
if?(isSuccess)?{
?message?=?'Operation?successful';
}?else?{
?message?=?'Operation?failed';
}
//?條件運(yùn)算符簡(jiǎn)化
const?message?=?isSuccess???'Operation?successful'?:?'Operation?failed';
7. 使用對(duì)象解構(gòu)和默認(rèn)參數(shù)簡(jiǎn)化函數(shù)參數(shù)
//?傳統(tǒng)參數(shù)設(shè)置默認(rèn)值
function?greet(name)?{
?const?finalName?=?name?||?'Guest';
?console.log(`Hello,?${finalName}!`);
?}
??
?//?對(duì)象解構(gòu)和默認(rèn)參數(shù)簡(jiǎn)化
?function?greet({?name?=?'Guest'?})?{
?console.log(`Hello,?${name}!`);
?}
8. 使用函數(shù)式編程概念如純函數(shù)和函數(shù)組合
//?純函數(shù)
function?add(a,?b)?{
?return?a?+?b;
?}
??
?//?函數(shù)組合
?const?multiplyByTwo?=?value?=>?value?*?2;
?const?addFive?=?value?=>?value?+?5;
?const?result?=?addFive(multiplyByTwo(3));
9. 使用對(duì)象字面量簡(jiǎn)化對(duì)象的創(chuàng)建和定義
//?傳統(tǒng)對(duì)象創(chuàng)建
const?person?=?{
?firstName:?'John',
?lastName:?'Doe',
?age:?30,
?};
??
?//?對(duì)象字面量簡(jiǎn)化
?const?firstName?=?'John';
?const?lastName?=?'Doe';
?const?age?=?30;
?const?person?=?{?firstName,?lastName,?age?};
10. 使用適當(dāng)?shù)拿妥⑨寔硖岣叽a可讀性
//?不好的
const?x?=?10;?//?設(shè)置x的值為10
function?a(b)?{
?return?b?*?2;?//?返回b的兩倍
}
//?好的
const?speed?=?10;?//?設(shè)置速度為10
function?double(value)?{
?return?value?*?2;?//?返回輸入值的兩倍
接著奏樂接著舞(實(shí)戰(zhàn)篇)?。?!
實(shí)戰(zhàn)
1. 優(yōu)雅的寫條件判斷代碼
簡(jiǎn)單的條件判斷邏輯用if else
?或者 三元運(yùn)算符, 一眼看過去還能知道說的啥,但是大量的if else
和疊加在一起的三元運(yùn)算符就是接盤俠的噩夢(mèng)~~~
給大家上一個(gè)三元運(yùn)算符疊加的案例,我是真實(shí)在項(xiàng)目中遇到過,cpu直接干爆~~~
<view>{{status===1?'成功':?status===2???'失敗'?:?status===3???'進(jìn)行中'?:?'未開始'?}}</view>
大概是這樣的,具體的項(xiàng)目代碼不好放在這里,小伙伴們意會(huì)就行。
復(fù)雜邏輯推薦使用對(duì)象Map寫法,符合人腦的邏輯,可讀性高,看著舒服~~~
1,普通的if else
let?txt?=?'';
if?(falg)?{
?txt?=?成功
}?else?{
?txt?=?失敗
}
2,三元運(yùn)算符
let txt = flag ? 成功 : 失敗;
3,多個(gè)if else
//?param?{status}?status?活動(dòng)狀態(tài):1:成功?2:失敗?3:進(jìn)行中?4:未開始
let?txt?=?'';
if?(status?==?1)?{
?txt?=?成功;
}?else?if?(status?==?2)?{
?txt?=?失敗;
}?else?if?(status?==?3)?{
?txt?=?進(jìn)行中;
}?else?{
?txt?=?未開始;
}
4,switch case
let?txt?=?'';
switch?(status)?{
?case?1:
?txt?=?成功;
?break;
?case?2:
?txt?=?成功;
?break;
?case?3:
?txt?=?進(jìn)行中;
?break;
?default:
?txt?=?未開始;
}
5,對(duì)象寫法
const?statusMap?=?{
?1:?成功,
?2:?失敗,
?3:?進(jìn)行中,
?4:?未開始
}
//調(diào)用直接?statusMapp[status]
6,Map寫法
const?actions?=?new?Map([
?[1,?成功],
?[2,?失敗],
?[3,?進(jìn)行中],
?[4,?未開始]
])
//?調(diào)用直接?actions.get(status)
2. 封裝條件語句
同上,if里的條件越多越不利于接盤俠的維護(hù),不利于人腦的理解,一眼看過去又是一堆邏輯。多個(gè)邏輯應(yīng)該化零為整
。
大腦:'別來碰我,讓我靜靜'
//?不好的
if?(fsm.state?===?'fetching'?&&?isEmpty(listNode))?{
?//?...
}
//?好的
shouldShowSpinner(fsm,?listNode){
?return?fsm.state?===?'fetching'?&&?isEmpty(listNode)
}
if(shouldShowSpinner(fsm,?listNode)){
?//...doSomething
}
3. 函數(shù)應(yīng)該只做一件事
函數(shù)式寫法推崇柯里化
, 一個(gè)函數(shù)一個(gè)功能,可拆分可組裝。
//?不好的
function?createFile(name,?temp)?{
?if?(temp)?{
???fs.create(`./temp/${name}`);
?}?else?{
???fs.create(name);
?}
}
//?好的
function?createFile(name)?{
?fs.create(name);
}
function?createTempFile(name)?{
?createFile(`./temp/${name}`)
}
再來一個(gè)栗子
函數(shù)要做的事情如下:
-
遍歷clients數(shù)組
-
遍歷過程中,通過lookup函數(shù)得到一個(gè)新的對(duì)象clientRecord
-
判斷clientRecord對(duì)象中isActive函數(shù)返回的是不是true,
-
isActive函數(shù)返回true,執(zhí)行email函數(shù)并把當(dāng)前成員帶過去
-
//?不好的
function?emailClients(clients)?{
?clients.forEach((client)?=>?{
???const?clientRecord?=?database.lookup(client);
???if?(clientRecord.isActive())?{
?????email(client);
???}
?});
}
//?好的
function?emailClients(clients)?{
?clients
???.filter(isClientRecord)
???.forEach(email)
}
function?isClientRecord(client)?{
?const?clientRecord?=?database.lookup(client);
?return?clientRecord.isActive()
}
上面不好的栗子一眼看過去是不是感覺一堆代碼在那,一時(shí)半會(huì)甚至不想去看了。
好的栗子,是不是邏輯很清晰,易讀。
-
巧用filter函數(shù),把filter的回調(diào)單開一個(gè)函數(shù)進(jìn)行條件處理,返回符合條件的數(shù)據(jù)
-
符合條件的數(shù)據(jù)再巧用forEach,執(zhí)行email函數(shù)
4. Object.assign給默認(rèn)對(duì)象賦默認(rèn)值
//?不好的
const?menuConfig?=?{
?title:?null,
?body:?'Bar',
?buttonText:?null,
?cancellable:?true
};
function?createMenu(config)?{
?config.title?=?config.title?||?'Foo';
?config.body?=?config.body?||?'Bar';
?config.buttonText?=?config.buttonText?||?'Baz';
?config.cancellable?=?config.cancellable?===?undefined??
?config.cancellable?:?true;
}
createMenu(menuConfig);
//?好的
const?menuConfig?=?{
?title:?'Order',
?buttonText:?'Send',
?cancellable:?true
};
function?createMenu(config)?{
?Object.assign({
???title:?'Foo',
???body:?'Bar',
???buttonText:?'Baz',
???cancellable:?true?
?},?config)
}
createMenu(menuConfig);
5. 函數(shù)參數(shù)兩個(gè)以下最好
說一千道一萬,就是為了優(yōu)雅,就是為了可讀性好。
//?不好的
function?createMenu(title,?body,?buttonText,?cancellable)?{
?//?...
}
//?好的
const?menuConfig?=?{
?title:?'Foo',
?body:?'Bar',
?buttonText:?'Baz',
?cancellable:?true
};
function?createMenu(config){
?//?...
}
createMenu(menuConfig)
6. 使用解釋性的變量
省流,用了擴(kuò)展運(yùn)算符,為了可讀性(saveCityZipCode(city, zipCode)
可讀性很好,知道參數(shù)是干嘛的)
//?不好的
const?address?=?'One?Infinite?Loop,?Cupertino?95014';
const?cityZipCodeRegex?=?/^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
saveCityZipCode(address.match(cityZipCodeRegex)[1],?address.match(cityZipCodeRegex)[2]);
//?好的
const?address?=?'One?Infinite?Loop,?Cupertino?95014';
const?cityZipCodeRegex?=?/^[^,\\]+[,\\\s]+(.+?)\s*(\d{5})?$/;
cosnt?[,?city,?zipCode]?=?address.match(cityZipCodeRegex)?||?[];
saveCityZipCode(city,?zipCode)
想對(duì)類中的屬性進(jìn)行更多自定義取/增/改的操作時(shí),使用set/get
第一次見這個(gè)寫法,不知道是啥意思的小伙伴,把他當(dāng)成vue2中的defineProperty
Object.defineProperty(data1,'age',{
?set:function(newAge){
???console.log(this.name+'現(xiàn)在'+newAge+'歲')
?},
?get:function(){
???return?18;
?}
})
是一個(gè)意思,賦值的時(shí)候set會(huì)被觸發(fā),取值的時(shí)候get會(huì)被觸發(fā)。
巧用自帶屬性,提升性能。
class?BankAccount?{
?constructor(balance?=?1000)?{
???this._balance?=?balance;
?}
?//?It?doesn't?have?to?be?prefixed?with?`get`?or?`set`?to?be?a
?//getter/setter
?set?balance(amount)?{
???console.log('set')
???if?(verifyIfAmountCanBeSetted(amount))?{
?????this._balance?=?amount;
???}
?}
?get?balance()?{
???console.log('get')
???return?this._balance;
?}
?verifyIfAmountCanBeSetted(val)?{
???//?...
?}
}
const?bankAccount?=?new?BankAccount();
//?Buy?shoes...
bankAccount.balance?-=?100;
//?Get?balance
let?balance?=?bankAccount.balance;
7. 讓對(duì)象擁有私有成員-通過閉包來實(shí)現(xiàn)
閉包天生就是做私有化的
//?不好的
const?Employee?=?function(name)?{
?this.name?=?name;
};
Employee.prototype.getName?=?function?getName()?{
?return?this.name;
};
const?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
//?好的
const?Employee?=?function(name){
?this.getName?=?function(){
???return?name
?}
}
const?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
第一個(gè)示例
優(yōu)點(diǎn):
-
通過
原型鏈共享方法
,節(jié)省了內(nèi)存空間。所有實(shí)例對(duì)象共享同一個(gè)?getName
?方法,而不是每個(gè)實(shí)例對(duì)象都創(chuàng)建一個(gè)獨(dú)立的方法。
缺點(diǎn):
-
在構(gòu)造函數(shù)中無法直接定義私有屬性或方法,
所有屬性和方法都會(huì)被暴露在原型鏈上
。
第二個(gè)示例
優(yōu)點(diǎn):
-
可以在構(gòu)造函數(shù)內(nèi)部
定義私有屬性和方法
,不會(huì)暴露在對(duì)象的原型鏈上,提供了更好的封裝性。
缺點(diǎn):
-
每次創(chuàng)建實(shí)例對(duì)象時(shí),都會(huì)創(chuàng)建一個(gè)獨(dú)立的方法,
每個(gè)實(shí)例對(duì)象都有
自己的?getName
?方法,占用更多的內(nèi)存空間。
8. 使用方法鏈
鏈?zhǔn)綄懛?/code>也是代碼優(yōu)雅之道的重頭戲。
ps:發(fā)明這個(gè)的程序員肯定是后端出身的,這種寫法在PHP的CI框架中見過。
//?不好的
class?Car?{
?constructor()?{
???this.make?=?'Honda';
???this.model?=?'Accord';
???this.color?=?'white';
?}
?setMake(make)?{
???this.make?=?make;
?}
?save()?{
???console.log(this.make,?this.model,?this.color);
?}
}
const?car?=?new?Car();
car.setMake('Ford');
car.save();
//?好的
class?Car?{
?constructor()?{
???this.make?=?'Honda';
???this.model?=?'Accord';
???this.color?=?'white';
?}
?setMake(make)?{
???this.make?=?make;
???//?NOTE:?return?this是為了用鏈?zhǔn)綄懛????return?this;
?}
?save()?{
???console.log(this.make,?this.model,?this.color);
???//?NOTE:return?this是為了用鏈?zhǔn)綄懛????return?this;
?}
}
const?car?=?new?Car()
?.setMake('Ford')
?.save();
看完上面的這么多栗子,小伙伴的思路是不是清晰了很多,在你們的項(xiàng)目里練練手吧。
你將收獲的是同事們、 接盤俠們的感恩和自己內(nèi)心的舒適?。。?/p>
完結(jié)
這篇文章我盡力把我的筆記和想法放到這了,希望對(duì)小伙伴有幫助。
歡迎轉(zhuǎn)載,但請(qǐng)注明來源。文章來源:http://www.zghlxwxcb.cn/news/detail-498660.html
最后,希望小伙伴們給我個(gè)免費(fèi)的點(diǎn)贊,祝大家心想事成,平安喜樂。文章來源地址http://www.zghlxwxcb.cn/news/detail-498660.html
到了這里,關(guān)于編寫魅力十足的代碼:優(yōu)化可讀性、維護(hù)性和性能的關(guān)鍵的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!