欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

如何在JavaScript中謹(jǐn)慎使用代碼注釋

 更新時(shí)間:2019年06月21日 16:30:46   作者:Harttle  
這篇文章主要介紹了如何在JavaScript中謹(jǐn)慎使用代碼注釋,必要的注釋可以闡明實(shí)現(xiàn)細(xì)節(jié)和設(shè)計(jì)意圖,以此節(jié)約自己和別人的時(shí)間。 然而很多時(shí)候注釋起的作用卻適得其反,,需要的朋友可以參考下

前言

最令程序員頭痛的事情莫過(guò)于閱讀別人的代碼,但其實(shí)時(shí)間一久閱讀自己的代碼也會(huì)很痛苦。 問(wèn)題不是出在『自己或別人』,而是在代碼本身。

必要的注釋可以闡明實(shí)現(xiàn)細(xì)節(jié)和設(shè)計(jì)意圖,以此節(jié)約自己和別人的時(shí)間。 然而很多時(shí)候注釋起的作用卻適得其反,比如自動(dòng)生成的過(guò)多的注釋分散閱讀者的注意力, 而過(guò)期的失效的注釋更是誤導(dǎo)閱讀者。

自動(dòng)生成的注釋

代碼注釋的泛濫想必是從Eclipse,Visual Studio等IDE開(kāi)始的。 這些IDE提供了很多快捷功能,生成類/接口的骨架,具有Getter/Setter的屬性等等。 如果用過(guò)IDE,下面的代碼你一定不會(huì)陌生:

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}

上述6行代碼中的4行注釋包含的信息量是0,既沒(méi)有闡釋參數(shù)args是何物,也沒(méi)有說(shuō)明main的用途。 然而大量的項(xiàng)目中都充斥著這樣的自動(dòng)生成注釋。

『建議』:如果有參數(shù)或機(jī)制需要說(shuō)明,請(qǐng)補(bǔ)充這些信息。否則請(qǐng)刪除自動(dòng)生成注釋。 當(dāng)然,用于生成文檔的注釋除外。

過(guò)多的注釋

總會(huì)有人不厭其煩地編寫(xiě)長(zhǎng)篇累牘的注釋,或無(wú)微不至,或語(yǔ)焉不詳,或晦澀難懂,或文采飛揚(yáng)。 總之沒(méi)有幫助我更快閱讀代碼的注釋都是失敗的注釋。

為了說(shuō)明問(wèn)題,Harttle克隆了4.x Linux Kernel源碼, 來(lái)大致分析一下其注釋行數(shù)。 我們知道內(nèi)核代碼95%以上是C語(yǔ)言,所以統(tǒng)計(jì).c文件就足夠說(shuō)明問(wèn)題了。

➜ linux git:(master) git clone git@github.com:torvalds/linux.git --depth=1
➜ linux git:(master) find . -name "*.c" -o -name "*.h" -exec grep -E '^\s*((\*)|(/[/*]))' {} \; | wc -l
724804
➜ linux git:(master) find . -name "*.c" -o -name "*.h" -exec cat {} \; | wc -l
4018961
➜ linux git:(master) node
> 724804/(4018961-724804)
0.22002715717556875

內(nèi)核倉(cāng)庫(kù)中的代碼大概是402萬(wàn)行(未移除空行),其中注釋72萬(wàn)行,占比22%。 Linux內(nèi)核使用低級(jí)的C語(yǔ)言編寫(xiě),涉及到復(fù)雜的CPU調(diào)度、內(nèi)存管理,驅(qū)動(dòng)程序。 因此注釋會(huì)偏多一些,一般的項(xiàng)目注釋?xiě)?yīng)小于這個(gè)數(shù)值。

『建議』:如果你的代碼中注釋超過(guò)了20%,那么顯然你過(guò)度注釋了。

文件頭注釋

很多編輯器/IDE都會(huì)生成默認(rèn)的文件頭,例如:

/**
* @file /tmp/xxx.js
* @author harttle(yangjvn@126.com)
* @date 2016-08-30 22:33
* @description A XXX Implementation for XXX.
*/

文件頭注釋清晰地列出了文件的作者、功能描述等信息,看起來(lái)很有用。 不過(guò)這樣的文件頭存在的問(wèn)題在于其維護(hù)性:

  • 其他人做小的修改時(shí)未必會(huì)修改@author,甚至連@author都不知道現(xiàn)在該文件已經(jīng)面目全非。
  • 每次移動(dòng)該文件,是否還需要花功夫更新 @file 信息?
  • 誰(shuí)會(huì)在每次代碼修改后記得更新 @description,于是@description也總是誤導(dǎo)讀者

文件頭注釋意在維護(hù)代碼文件的元信息,以便在分發(fā)和部署過(guò)程中維護(hù)作者版權(quán)等信息。 然而在擁有版本控制的代碼倉(cāng)庫(kù)中,這些信息不再需要手動(dòng)維護(hù),甚至可以通過(guò)git blame查看每一行代碼的作者和時(shí)間信息。

『建議』:使用版本控制工具,刪除文件頭注釋。版權(quán)信息可在構(gòu)建或分發(fā)時(shí)生成。

冗余的注釋

意圖非常清楚的代碼原則上不需要注釋,多余的注釋反而會(huì)造成維護(hù)性問(wèn)題。 尤其是非英語(yǔ)母語(yǔ)的作者常常會(huì)掉到這個(gè)坑里。比如變量和函數(shù)的注釋:

/*
* 獲取用戶數(shù)目
*/
function getUserCount(){
// 用戶的列表
var userList = [];
}

這不是廢話么!冗余的注釋問(wèn)題仍然在于維護(hù)性,例如調(diào)整函數(shù)功能、調(diào)整參數(shù)順序, 或者更換變量名時(shí)我們不得不更新這些注釋。否則這些注釋就會(huì)誤導(dǎo)下一個(gè)讀者。

【建議】:不說(shuō)廢話。

抽取注釋到標(biāo)識(shí)符

可能讀者也會(huì)有這樣的經(jīng)驗(yàn):當(dāng)我們寫(xiě)了一大段代碼時(shí),往往需要把它們分為幾塊。 然后在每一塊開(kāi)頭添加一段注釋。例如:

function calcTotalCharge(movies, user){
// Calculate Movie Charge
var movieCharge = 0;
for(var i=0; i<movies.length; i++){
var charge = 0;
if(movie.type === 'discount'){
charge = movie.charge * 0.8;
}
else if(movie.type === 'short'){
charge = movie.charge * 2;
}
else if(movie.type === 'normal'){
charge = movie.charge;
}
movieCharge += charge;
}

// Calculate User Charge
var rentCharge = 0;
if(user.isVIP1){
rentCharge = 10;
}
if(user.isVIP2){
rentCharge = 200;
}
else if(user.isVIP3){
rentCharge = 300;
}
else if(user.isVIP4){
rentCharge = 500;
}
// Calculate Total Charge
return movieCharge + rentCharge;
}

上述代碼中的三段注釋確實(shí)加速了閱讀代碼的速度, 但每當(dāng)代碼需要注釋才能讀懂時(shí)就應(yīng)該警醒:是不是結(jié)構(gòu)設(shè)計(jì)有問(wèn)題。 對(duì)于上述代碼,我們可以通過(guò)更加可復(fù)用的結(jié)構(gòu)來(lái)消除注釋:

function calcTotalCharge(movies, user){
return calcMovieCharge(movies) + calcUserCharge(user);
}
function calcMovieCharge(movies){
var total = 0;
for(var i=0; i<movies.length; i++){
total += calcSingleMovieCharge(movie);
}
return total;
}
function calcSingleMovieCharge(movie){
if(movie.type === 'discount') return movie.charge * 0.8;
else if(movie.type === 'short') return movie.charge * 2;
else if(movie.type === 'normal') return movie.charge;
return 0;
}
function calcUserCharge(user){
if(user.isVIP1) return 10;
else if(user.isVIP2) return 200;
else if(user.isVIP3) return 300;
else if(user.isVIP4) return 500;
return 0;
}

代碼重構(gòu)之后原來(lái)的注釋就變得毫無(wú)意義,代碼意圖都被清晰的表述在標(biāo)識(shí)符的命名中。 通常重構(gòu)會(huì)帶來(lái)代碼量的減小,因?yàn)榉庋b了分支、每個(gè)單元的邏輯也更加明確。

【建議】:當(dāng)我們發(fā)現(xiàn)不得不進(jìn)行注釋時(shí),需要警醒是否結(jié)構(gòu)設(shè)計(jì)發(fā)生了問(wèn)題。

有用的注釋

至此Harttle已描述了這么多反模式,并非為了說(shuō)明代碼注釋不重要。 而是為了說(shuō)明『代碼注釋存在的意義在于幫助理解代碼本身』。 例如在編寫(xiě)一些Trick,Polyfill,臨時(shí)代碼,以及復(fù)雜算法時(shí),注釋變得相當(dāng)重要。 例如:

  • Tricks and Polyfills。有時(shí)簡(jiǎn)單的Trick就可解決多數(shù)問(wèn)題問(wèn)題, 為沒(méi)必要編寫(xiě)復(fù)雜的普適算法, 例如檢測(cè)瀏覽器的DOM API支持,檢測(cè)AMD/CommonJS環(huán)境等等。 這時(shí)我們需要清晰地說(shuō)明這些Trick的意圖,甚至可以將這些代碼抽離為polyfill模塊。
  • 復(fù)雜算法。有時(shí)我們會(huì)編寫(xiě)數(shù)學(xué)性非常強(qiáng)的算法,一眼望去不知所云。 在開(kāi)始這些算法前清晰地說(shuō)明其意圖何在,讀者也就不必花大功夫讀懂這些數(shù)學(xué)了。
  • 公有接口。模塊的對(duì)外接口從邏輯上定義了模塊類型,公有接口代碼也更容易被人讀到。 尤其是JavaScript接口:如果不注釋options中到底是什么,誰(shuí)曉得接口如何使用。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Js與Jq獲取瀏覽器和對(duì)象值的方法

    Js與Jq獲取瀏覽器和對(duì)象值的方法

    這篇文章主要介紹了 Js與Jq獲取瀏覽器和對(duì)象值的方法的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • 微信小程序?qū)崿F(xiàn)橫屏手寫(xiě)簽名

    微信小程序?qū)崿F(xiàn)橫屏手寫(xiě)簽名

    這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)橫屏手寫(xiě)簽名,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • 基于JavaScript構(gòu)建高級(jí)視頻播放器

    基于JavaScript構(gòu)建高級(jí)視頻播放器

    這篇文章主要為大家詳細(xì)介紹了如何基于JavaScript構(gòu)建高級(jí)視頻播放器,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-04-04
  • javascript實(shí)現(xiàn)發(fā)送短信倒計(jì)時(shí)

    javascript實(shí)現(xiàn)發(fā)送短信倒計(jì)時(shí)

    這篇文章主要為大家詳細(xì)介紹了javascript實(shí)現(xiàn)發(fā)送短信倒計(jì)時(shí),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • JS實(shí)現(xiàn)簡(jiǎn)單抖動(dòng)效果

    JS實(shí)現(xiàn)簡(jiǎn)單抖動(dòng)效果

    這篇文章給大家結(jié)束了通過(guò)js實(shí)現(xiàn)抖動(dòng)效果,非常不錯(cuò),具有參考借鑒價(jià)值,感興趣的朋友參考下吧
    2017-06-06
  • JavaScript編寫(xiě)推箱子游戲

    JavaScript編寫(xiě)推箱子游戲

    本文給大家介紹的是使用javascript來(lái)實(shí)現(xiàn)一款經(jīng)典的老游戲--推箱子,主要側(cè)重于實(shí)現(xiàn)的思路,最后附上源碼給大家。
    2015-07-07
  • 微信小程序之onLaunch與onload異步問(wèn)題詳解

    微信小程序之onLaunch與onload異步問(wèn)題詳解

    這篇文章主要介紹了微信小程序之onLaunch與onload異步問(wèn)題詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • 微信小程序canvas開(kāi)發(fā)水果老虎機(jī)的思路詳解

    微信小程序canvas開(kāi)發(fā)水果老虎機(jī)的思路詳解

    這篇文章主要介紹了微信小程序canvas開(kāi)發(fā)水果老虎機(jī)的思路,本文通過(guò)思路代碼分步驟給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • 簡(jiǎn)單實(shí)例處理url特殊符號(hào)&處理(2種方法)

    簡(jiǎn)單實(shí)例處理url特殊符號(hào)&處理(2種方法)

    url里的參數(shù)內(nèi)容包含&符合,我有兩種方法解決一是:在頁(yè)面用JS轉(zhuǎn)碼;二是:在后端處理,另外還有網(wǎng)絡(luò)分享的一些方法,感興趣的朋友可以參考下哈
    2013-04-04
  • 原生js實(shí)現(xiàn)電商側(cè)邊導(dǎo)航效果

    原生js實(shí)現(xiàn)電商側(cè)邊導(dǎo)航效果

    本文主要分享了原生js實(shí)現(xiàn)電商側(cè)邊導(dǎo)航效果的示例代碼以及原理分析。具有很好的參考價(jià)值,下面跟著小編一起來(lái)看下吧
    2017-01-01

最新評(píng)論