本節書摘來自異步社群《編寫可維護的javascript》一書中的第2章,第2.3節,作者:【美】nicholas c. zakas著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視
何時添加注釋是程式員經常争論的一個話題。一種通行的指導原則是,當代碼不夠清晰時添加注釋,而當代碼很明了時不應當添加注釋。比如這個例子中,注釋是畫蛇添足。
因為代碼中初始化count的操作是顯而易見的。注釋并沒有提供其他有價值的資訊。換個角度講,如果這個值10具有一些特殊的含義,而且無法直接從代碼中看出來,這時就有必要添加注釋了。
當然不可能因為修改了count的值它就變成了青蛙,但這的确是一個好的注釋寫法的例子,因為注釋中給出了必要的資訊,如果沒有注釋,你不可能獲得這些資訊。想象一下如果你修改了count的值它真的變成了青蛙,實在是讓人困惑不解,一切都源于你沒有寫這句注釋。
是以,添加注釋的一般原則是,在需要讓代碼變得更清晰時添加注釋。
2.3.1 難于了解的代碼
難于了解的代碼通常都應當加注釋。根據代碼的用途,你可以用單行注釋、多行注釋,或是混用這兩種注釋。關鍵是讓其他人更容易讀懂這段代碼。比如,這段示例代碼摘自yui類庫中的y.mix()方法。
y.mix()方法使用常量來決定如何處理。mode參數就表示這些常量其中之一,但僅僅通過這些數值無法了解它們各自代表的含義。這裡的注釋非常棒,因為它及時地解釋了這裡複雜的決策邏輯。
2.3.2 可能被誤認為錯誤的代碼
另一個适合添加注釋的好時機是當代碼看上去有錯誤時。在團隊開發中,總是會有一些好心的開發者在編輯代碼時發現他人的代碼錯誤,就立即将它修複。有時這段代碼并不是錯誤的源頭,是以“修複”這個錯誤往往會制造其他錯誤,是以本次修改應當是可追蹤的。當你寫的代碼有可能會被别的開發者認為有錯誤時,則需要添加注釋。這裡是另一段來自yui源碼的例子。
while (element &&(element = element[axis])) { // 提示: 指派操作 if ( (all || element[tag_name]) && (!fn || fn(element)) ) { return element; } } 在這個例子中,開發者在while循環控制條件中使用了一個指派運算符。這不是一種标準用法,并常常被檢測工具認為是有問題的。如果你對這段代碼不熟悉,讀到這段沒有注釋的代碼時,很可能誤以為這是一個錯誤,猜想作者的本意是使用比較運算符==而不是指派運算符=。這行末尾的注釋說明作者是有意為之,即指派而非比較。這樣,其他開發者在讀到這段代碼時就不會将它“修複”。
2.3.3 浏覽器特性hack
javascript程式員常常會編寫一些低效的、不雅的、徹頭徹尾的肮髒代碼,用來讓低級浏覽器正常工作。實際上這種情形是一種特殊的“可能被誤認為錯誤的代碼”:這種不明顯的做浏覽器特性hack的代碼可能隐含一些錯誤。這裡有個例子,是摘自yui類庫的y.dom.contains()方法。
這段代碼的第6行包含一條重要的注釋。盡管ie和safari中都有内置方法contains(),但如果needle不是一個元素時,這個方法會報錯。是以隻有當浏覽器是opera時才能用這個方法,其他浏覽器中needle必須是一個元素(nodetype是1)。這裡關于浏覽器的說明同樣解釋了為什麼需要一個if語句,這個注釋不僅確定将來不會被其他人誤改動,而且在代碼編寫者回過頭閱讀自己的這段代碼時,也會适時地針對新版本的ie和safari的相容情況做出調整。