日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

这些被同事喷的JS代码风格你写过多少?

發布時間:2023/12/10 javascript 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 这些被同事喷的JS代码风格你写过多少? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:殷榮檜@騰訊

來自:https://github.com/jackiewillen/blog/issues/14


現在寫代碼比以前好多了,代碼的格式都有 eslint、prettier、babel(寫新版語法) 這些來保證,然而,技術手段再高端都不能解決代碼可讀性(代碼能否被未來的自己和同事看懂)的問題,因為這個問題只有人自己才能解決。我們寫代碼要寫到下圖中左邊這樣基本上就功德圓滿了。

一、變量相關

(1)變量數量的定義


NO:濫用變量


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: 數據只使用一次或不使用就無需裝到變量中

let?kpi?=?4;??//?沒用的就刪除掉,不然過三個月自己都不敢刪,怕是不是那用到了
function?example()?{
????var?a?=?1;
????var?b?=?2;
????return?2a+b+1;
}

(2)變量的命名

NO:自我感覺良好的縮寫

let?fName?=?'jackie';?//?看起來命名挺規范,縮寫,駝峰法都用上,ESlint各種檢測規范的工具都通過,But,fName是啥?這時候,你是不是想說What?are?you?弄啥呢?
let?lName?=?'willen';?//?這個問題和上面的一樣

YES:無需對每個變量都寫注釋,從名字上就看懂

?let?firstName?=?'jackie';?//?怎么樣,是不是一目了然。少被噴了一次
?let?lastName?=?'willen';
??```

(3)特定的變量

NO:無說明的參數

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);?//?truefalse啥意思,一目不了然

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']()

三、盡量使用ES6,有可以能的話ES7中新語法

(只羅列最常用的新語法,說實話,有些新語法不怎么常用)

(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()?{
????/*?...?*/
??}
}

先寫到這了,這是目前為止發現的問題,這篇文章中并沒有完全覆蓋到常見的寫代碼的不好的習慣,所以你如果覺的有需要補充的,都可以在文章下方評論,或者直接到我的Github的這篇文章中評論。對于有用的,都將補充到我的掘金和Github中去。同時,你如果覺的文章寫得還可以,Please在我的Github中送上你寶貴的Star,你的Star是我繼續寫文章最大的動力。

注:除了上述這些人為習慣之外,就像前面提到的,對于機械性的,你可以使用Babel、Eslint、Prettier這些工具來保證代碼的格式一致。

參考資料

https://blog.risingstack.com/javascript-clean-coding-best-practices-node-js-at-scale/(JavaScript Clean Coding Best Practices)

https://www.zhihu.com/question/20635785?(如何寫出優美的 JavaScript 代碼?)


總結

以上是生活随笔為你收集整理的这些被同事喷的JS代码风格你写过多少?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。