Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
多編程技術文章,請查閱IOKKS - 專業編程技術分享平臺
這并不是什么秘密,開發人員必須思考眾多日常任務。他們的一部分思考總是專注于各種例行事務,比如“我應該把這個函數放在哪個模塊?”,“我應該如何命名這個變量?”,或者“這個變量應該做什么?”盡管這些問題看起來簡單而瑣碎,但它們一直在消耗著心智資源。然而,如果有辦法通過自動化一些例行任務來簡化這個過程,從而將注意力集中在更為關鍵的事務上,那么利用這些方法無疑是明智的。
在這種情況下,命名約定起著至關重要的作用。了解并明智地應用這些約定有助于增強代碼的可讀性,簡化理解,并減輕開發人員的認知負擔。然而,并非所有開發人員都清楚并且有時會忘記如何正確應用這些約定,盲目地將他們的注意力轉移到看似更為關鍵的事務上。這反過來使他們的代碼的可讀性和理解變得復雜,使表面上“更為關鍵”的任務比實際上可能更為復雜。
以下是我有機會參與的一個真實項目的截圖。請注意每個導入。根據名稱,嘗試猜測 我們可以從每個導入中獲得什么項目。
在本文中,我們將探討其中大部分內容,學習或者提醒自己在編寫構造時應該遵循哪些原則。這將有助于你和未來與你的代碼一起工作的任何人,無論是你的團隊還是你自己 在一段時間后,避免猜測 并增強你的代碼的可讀性。
本文將包括一系列命名建議。我不希望你將它們視為唯一的真理。首先,這并不完全正確,因為大多數建議都帶有一項免責聲明,暗示這些約定本身并不涵蓋所有情況。其次,雖然大多數建議在 JavaScript 社區中得到了接受,但并非所有人都出于各種原因遵循它們,有些建議被部分或者顯著修改以適應特定團隊。
本文的主要觀點是,每個項目都應該建立自己的命名約定,無論它們是否與廣泛采用的約定一致,還是獨特于你的團隊。關鍵的一點是要有約定并且遵守它們。
在互聯網上,有大量關于最佳命名實踐的文章。眾所周知的約定強調,名稱應該是簡短的,更重要的是,可理解的 。名稱應該具體,與其使用的上下文相對應,并且一目了然地傳達代碼的含義。實際上,這些約定不僅可以而且應該不僅在使用 JavaScript 時,而且在使用任何編程語言時都應該被應用。在這些通用規則中,我想重點關注一些約定中的特定細節,這些約定是廣為人知的,但經常被遺忘或者沒有完全遵守。
統一性 。在 JavaScript 項目中,有許多約定,但最有價值的約定是在單個項目中保持一致的編碼風格。參與不同項目的個人最清楚不過,編寫風格在不同項目之間可能會有顯著的差異。
通常會出現這樣的情況,即應用的不同部分由不同團隊開發,或者在其開發中使用不同的技術。根據所選擇的編程語言或者開發團隊的偏好,命名約定可能會有所不同。盡管存在這些差異,應用的不同部分需要相互交互,比如前端和后端之間的數據交換。例如,從后端請求的數據的命名風格可能與前端代碼中使用的風格不同。
盡管 JavaScript 語言的約定是使用 camelCase,但值得注意的是,并沒有阻止使用,例如,snake_case。正如前面提到的,這種表示法對許多其他編程語言和一些團隊來說可能更為熟悉。可能會出現這樣的情況,即與你的應用程序風格不同的命名風格開始滲入你的代碼。
我們無權判斷使用不同的命名風格是好是壞,因為各種原因可能推動這樣的選擇。然而,明確地混合兩種或更多種命名風格可能會帶來挑戰。對于加入項目的新開發人員來說,理解正在發生的事情并決定使用哪種命名風格可能會變得非常具有挑戰性。
// 不好
const hasAccess=checkHasUserAccess(session.current_user) && checkIsPageVisible(session.current_page)
// 好
const hasAccess=checkHasUserAccess(session.currentUser) && checkIsPageVisible(session.currentPage)
// 如果偏好這種命名風格,也是好的
const has_access=check_has_user_access(session.current_user) && check_is_page_visible(session.current_page)
有幾種方法可以解決這個問題,從使用 解構賦值、導入重命名、使用映射函數(例如 Array.prototype.map()),到更高級的方法,比如利用 適配器 設計模式。
關鍵在于采用一致的方法,不僅在命名約定上,而且在任務完成方式上也是如此。在可能的情況下,最好為特定操作選擇一種方法。避免強迫自己和其他開發人員花費時間和額外的心智資源來決定使用哪種方法。考慮委托這樣的任務,特別是與編碼風格相關的任務,給工具。
僅限英文 。盡管在 JavaScript 中寫作時可以使用非拉丁字母,但不建議這樣做。即使你為自己編寫某些東西,每一行代碼都有“長壽”的能力,可能會有一天你需要與其他開發人員分享這些代碼。對于其他開發人員,尤其是來自不同國家的開發人員,理解代碼中發生的事情將會很困難。
在強調僅使用英文時,人們通常只考慮鍵盤布局。然而,人們不應忘記縮寫和名稱的一般使用。它們應該只與常用詞一起使用,比如 idx、err、evt、xhr、src 等社區中歷史上被接受的詞。在其他情況下,強烈不建議使用縮寫和詞語的簡寫,因為它們經常會導致混淆,并且解密它們可能需要很長時間。
// 不好
const 新規ユーザーのウェルカムメッセージ='こんにちは'
const usrInf={ fName: 'John', lName: 'Doe' }
const isAdult=a >=18
// 好
const newUserWelcomeMessage='こんにちは'
const userInfo={ firstName: 'John', lastName: 'Doe' }
const isAdult=userAge >=18
還建議在代碼編輯器中啟用拼寫檢查器,它將突出顯示單詞中的語法錯誤。在許多編輯器中,默認情況下已啟用,對于某些編輯器,你可能需要安裝一個擴展,比如 VS Code 的 Code Spell Checker。今天的拼寫檢查器足夠智能,大多數被廣泛接受的縮寫和詞語的簡寫不會被標記為錯誤。
不僅僅是 camelCase 。許多資源強調在 JavaScript 中寫作時專門 使用 camelCase 表示法。然而,這并不完全準確。建議更多地是關于遵循語言本身使用的表示法 。雖然 JavaScript 語言的大部分 是使用 camelCase 編寫的,但并非完全如此。以下是一些例子:
parseInt('18') // camelCase
new RegExp('[A-Z]', 'i') // PascalCase
Number.MAX_SAFE_INTEGER // PascalCase + UPPER_SNAKE_CASE
正如我們所看到的,JavaScript 不僅包括 camelCase 表示法,還包括其他一些表示法。JavaScript 中的所有類和構造函數都是使用 PascalCase 表示法編寫的。在聲明自定義類和構造函數時,習慣上要遵循與語言本身相同的命名約定。對于表示固定值的常量也是如此。無論是 JavaScript 內置的常量還是開發人員創建的常量,通常都是以 UPPER_SNAKE_CASE 命名的。
與一些編程語言不同,其 API 使用各種表示法而沒有明確的分布不同,JavaScript 的 API 并不受此問題的困擾。因此,遵循語言本身中存在的約定是慣例。
遵循 readme.md 。假設你正在使用像 axios 這樣的網絡請求庫,并且該庫的 README 建議使用標準名稱 axios 進行導入。
import httpRequester from 'npm:axios'
// 在文件的底部的某個地方
httpRequester('https://example.com')
將名稱從 axios 更改為 httpRequester 可能會導致混淆和錯誤,因為其他在項目中工作并期望標準名稱 axios 的開發人員可能會遇到問題。因此,遵循庫的 README 中設置的建議是非常重要的,以確保兼容性和代碼理解。
乍一看,使用 axios 庫的示例可能看起來無害,但類似的重命名場景可能會出現在更深度集成到項目中的更復雜的庫和框架的使用中。采用有意義的重命名實踐的團隊將需要創建自己的文檔,因為新團隊成員在官方文檔中找不到足夠的信息來理解技術的使用風格的變化。
通常情況下,將更抽象的重命名用于與 依賴反轉原則 結合使用。然而,理解這里的微妙之處是很重要的。你和你的團隊必須清楚地了解你正在做什么以及為什么,因為在采用這樣的實踐時需要保持平衡。
不包含數據類型 。在變量名稱中包含數據類型可能是誘人的,但屈服于這種誘惑通常會給名稱增加不必要的語義負荷。例如,對于包含數組的變量使用名稱 arr 可能會導致沖突,如果在其他地方使用相同名稱的變量。此外,名稱 arr 并不傳達有意義的信息。使名稱更具體,比如 userArr,是一種改進,但它并不能解決所有問題。
// 不好
const userNameMinLengthConst=3
const userObj=getUser()
const getUniqueUserNames=(arr)=> Array.from(new Set(arr))
// 好
const USER_NAME_MIN_LENGTH_COUNT=3
const user=getUser()
const getUniqueUserNames=(names)=> Array.from(new Set(names))
對于每種語言構造,無論是內置的還是自定義的數據結構,都存在一種傳統的方式來指示值的預期數據類型。這體現在構造的名稱中,它應該與社區內部和團隊內部的約定一致。建議優先考慮社區約定,因為解釋一些被廣泛接受的東西通常比引入完全獨特的東西更容易。在社區約定的情況下,你可以將某人引用到一篇互聯網文章,而對于團隊特定的約定,你可能需要自己編寫這篇文章。
在本節中,我們將討論數據類型和數據結構的特定命名約定。雖然 JavaScript 在其內置數據類型和結構方面可能顯得有限,但它提供了廣泛的功能。這些功能包括各種方法,在其他編程語言中,這些方法通常被分隔成不同的內置類型或數據結構。
例如,在 JavaScript 中,對象可以用作 enum、map(dictionary)、graph 等。JavaScript 中的 number 數據類型包括處理整數和浮點數。根據具體要求,JavaScript 的數據類型和結構可以靈活地適應使用,為 JavaScript 提供了多樣性和強大性。
正是在這種情況下,命名約定的重要性變得明顯。它們不僅增強了代碼的可讀性,還在與代碼庫的其他部分交互時防止混淆和錯誤。良好的命名約定確保了代碼的清晰性,并有助于其他開發人員理解數據結構及其目的,從而促進團隊內更有效的協作。
布爾值 。布爾值的名稱應以肯定前綴開頭,即前綴應回答“是”的問題。雖然有幾個肯定的詞(should、can、will 等)可以回答“是”,但建議優先選擇最常見的兩個詞——is 和 has。雖然使用其他肯定詞不會被視為錯誤,但應將其視為例外情況,如果可能的話,最好避免使用它們。
這一約定的一個重要補充,經常被忽視的是,肯定前綴不應包括否定。其背后的原因是,否定運算符(!)最常用于布爾值。因此,一個命名為 isNotAllowed 的值,應用了否定 !isNotAllowed,可能會相當誤導。不相信嗎?那就試著快速弄清楚 !!isNotAllowed(雙重否定)等于什么。即使你能迅速做到,想象一下在整個文件中散布著所有這些否定反轉的真實代碼中工作。跟蹤這樣的邏輯,尤其是當有很多邏輯時,可能會相當具有挑戰性。在這種情況下,最好通過使用名稱中的積極肯定來改變評估布爾變量的邏輯。
函數和方法 。函數/方法的名稱應該是一個動詞,并對應它執行的動作。
盡管函數/方法的命名約定乍看起來可能很簡單,但它們的命名是最有例外和其他約定的。對于大多數函數和方法,主要約定是名稱應該是一個動詞,并對應它們執行的動作。
集合和迭代器 。命名約定如下——如果使用了迭代器或索引集合(例如 Array、NodeList、FileList 等),名稱應該是一個復數名詞。否則,如果使用了鍵控集合(Set、Map),并且我們只對可以通過鍵獲得的值感興趣(通常使用 Array.from() 或擴展語法),命名約定保持不變——名稱應該是一個復數名詞。但是,如果鍵對我們也很重要,那么這樣的集合應該使用單數名詞命名,并在名稱末尾添加表示一組某物的前綴之一。例如,Collection、List、Group 等。
類 。在處理類時,遵循幾個約定是很重要的。以下是列表:
常量 。用于描述在程序執行之前已知且在執行過程中不應更改的值。
關于命名約定,開發人員之間有一個重要的共識:常量的名稱應使用 UPPER_SNAKE_CASE 表示法。
枚舉 。在 JavaScript 中,這種數據結構用于枚舉一組固定值。
與許多其他編程語言具有枚舉的單獨數據類型不同,JavaScript 沒有這樣的數據類型(至少目前沒有)。因此,為了在 JavaScript 中模擬枚舉,可以使用一個普通對象,但需要遵循特定的命名約定。以下是這些命名約定的列表:
由于 TypeScript 現在是 JavaScript 開發的重要組成部分,值得一提的是 TypeScript 具有用于枚舉的 enum 關鍵字。如果決定與團隊一起使用 TypeScript 的枚舉,慣例是遵循相同的命名約定。
地圖 。也被稱為字典數據結構。這種數據結構用于將一個值映射到另一個值。
地圖是任何編程語言中非常有用且經常使用的數據結構。在JavaScript世界中,地圖有特定的命名約定。名稱應遵循aToB的模式,其中a作為從地圖中檢索值的鍵,后跟介詞To,暗示著兩個事物的映射,然后是B,它是a的映射值。
// 不好的
const userRolesReadable={
[UserRole.ADMIN]: '管理員',
[UserRole.GUEST]: '訪客',
}
const REDIRECTING={
'/groups': '/admin-login',
'/profile': '/login',
}
const UserPermissions={
[UserRole.ADMIN]: [Permission.MANAGE_USERS, Permission.MANAGE_GROUPS],
[UserRole.GUEST]: [Permission.EDIT_PROFILE],
}
// 好的
const userRoleToReadable={
[UserRole.ADMIN]: '管理員',
[UserRole.GUEST]: '訪客',
}
const pagePathToRedirectPath={
'/groups': '/admin-login',
'/profile': '/login',
}
const userRoleToPermissions={
[UserRole.ADMIN]: [Permission.MANAGE_USERS, Permission.MANAGE_GROUPS],
[UserRole.GUEST]: [Permission.EDIT_PROFILE],
}
JavaScript中有一個內置的Map類。與常規對象的主要區別在于能夠使用任何數據類型(甚至是對象)作為鍵。通常情況下,使用原生的Map類來創建地圖作為數據結構是多余的。但是,如果您需要原生Map提供的功能,可以使用它來創建地圖數據結構。在大多數情況下,常規對象就足夠了。
類型和接口 。如前所述,TypeScript已成為當今JavaScript開發中不可或缺的一部分。一般來說,在大多數情況下,類型和接口是可以互換的。然而,由于已經有足夠的討論關于選擇哪種,本文將專注于命名。對于類型和接口,存在以下命名約定:
// 不好的
type TUser={
firstName: string
lastName: string
}
interface user {
firstName: string
lastName: string
}
interface userServiceInterface {
findByEmail: (email: string)=> User
}
// 好的
type User={
firstName: string
lastName: string
}
interface User {
firstName: string
lastName: string
}
interface UserServiceContract {
findByEmail: (email: string)=> User
}
// 也可以
interface IUserService {
findByEmail: (email: string)=> User
}
重要的是要意識到,盡管本文對JavaScript命名約定進行了廣泛的概述,但它無法涵蓋所有可能的情況。即使在提出的觀點中,也應考慮許多例外情況。命名過程雖然基礎,但意味著在應用中靈活性,考慮到每個項目的獨特特點和要求。
在開發過程中,我們經常深入復雜的技術細節,忘記了力量常常隱藏在細節中。多年的開發經驗只能證實這樣一個事實,即對細節的關注,比如命名,對于創建高效和可讀的代碼起著至關重要的作用。簡潔和無需思考如何命名一個值以及如何快速理解它所包含的內容,為開發人員的日常工作帶來了難以置信的輕松。
如果一個開發人員的變量沒有被清晰命名,他們能否認為自己是強大的?清晰的命名不僅使代碼對其他開發人員更易理解,也使程序員自己更易理解,從而使開發過程更高效,減少錯誤。
經常發生的情況是,尋找糟糕的命名會導致發現糟糕的代碼。這只強調了命名約定作為代碼質量指標的重要性。適當的命名反映了對細節的關注,進而表明了對開發的細致態度。
當應用本文討論的約定時,從前言部分導入值的方式看起來更清晰了,不是嗎?我相信現在理解每個導入的含義將需要您付出更少的努力。
在結論中,重要的是要記住,雖然命名標準很重要,但它們并不是絕對的。每個項目都有其特殊性,定義自己的約定至關重要。最重要的是它們應該存在,并且您應該遵循它們,以確保代碼的一致性并提高集體生產力。此外,如果可能的話,嘗試將代碼風格問題委托給諸如ESLint之類的工具,以簡化和增強開發過程。
SS命名規范:
喜歡的給作者點個關注哦,想要學習資料的私聊
TML 符號實體
HTML 符號是不呈現在標準的鍵盤上,比如數學運算符、箭頭符號、技術符號和形狀。
如需向 HTML 頁面添加這些符號,您可以使用 HTML 實體名稱。
如果不存在實體名稱,您可以使用實體編號。
如果字符沒有實體名稱,您可以使用十進制(或十六進制)引用。
實例
<p>我將顯示 €</p>
<p>我將顯示 €</p>
<p>我將顯示 €</p>
結果如下:
我將顯示
我將顯示
我將顯示
HTML 支持的數學符號
如果您使用的是一個 HTML 實體名稱或一個十六進制編號,字符總是能正確顯示。
這是與您頁面使用的字符集相互獨立的!
字符 | 編號 | 實體 | 描述 |
---|---|---|---|
? | ∀ | ∀ | 所有(for all) |
? | ∂ | ∂ | 部分(part) |
? | ∃ | ∃ | 存在(exists) |
? | ∅ | ∅ | 空(empty) |
? | ∇ | ∇ | 倒三角(nabla) |
∈ | ∈ | ∈ | 屬于(isin) |
? | ∉ | ∉ | 不屬于(notin) |
? | ∋ | ∋ | 包含的成員(ni) |
∏ | ∏ | ∏ | 連乘(prod) |
∑ | ∑ | ∑ | 總和(sum) |
完整的數學(Math)參考手冊
HTML 支持的希臘字母
字符 | 編號 | 實體 | 描述 |
---|---|---|---|
Α | Α | Α | Alpha(中文注音:阿耳法) |
Β | Β | Β | Beta(中文注音:貝塔) |
Γ | Γ | Γ | Gamma(中文注音:伽馬) |
Δ | Δ | Δ | Delta(中文注音:德耳塔) |
Ε | Ε | Ε | Epsilon(中文注音:艾普西隆) |
Ζ | Ζ | Ζ | Zeta(中文注音:截塔) |
完整的希臘(Greek)參考手冊
HTML 支持的其他實體
字符 | 編號 | 實體 | 描述 |
---|---|---|---|
? | © | © | 版權所有(REGISTERED SIGN) |
? | ® | ® | 注冊商標(REGISTERED SIGN) |
| € | € | 歐元符號(EURO SIGN) |
? | ™ | ™ | 商標(trademark) |
← | ← | ← | 向左箭頭(LEFTWARDS ARROW) |
↑ | ↑ | ↑ | 向上箭頭(UPWARDS ARROW) |
→ | → | → | 向右箭頭(RIGHTWARDS ARROW) |
↓ | ↓ | ↓ | 向下箭頭(DOWNWARDS ARROW) |
? | ♠ | ♠ | 黑桃(BLACK SPADE SUIT) |
? | ♣ | ♣ | 黑梅花(BLACK CLUB SUIT) |
? | ♥ | ♥ | 黑心(BLACK HEART SUIT) |
? | ♦ | ♦ | 黑方塊(BLACK DIAMOND SUIT) |
如您還有不明白的可以在下面與我留言或是與我探討QQ群308855039,我們一起飛!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。