整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          JavaScript代碼風格參考指南

          碼必須盡可能的清晰和易讀。

          這實際上是一種編程藝術 —— 以一種正確并且人們易讀的方式編碼來完成一個復雜的任務。一個良好的代碼風格大大有助于實現這一點。

          一、語法

          下面是一個備忘單,其中列出了一些建議的規則(詳情請參閱下文):

          現在,讓我們詳細討論一下這些規則和它們的原因吧。

          沒有什么規則是“必須”的

          沒有什么規則是“刻在石頭上”的。這些是風格偏好,而不是宗教教條。

          二、花括號

          在大多數的 JavaScript 項目中,花括號以 “Egyptian” 風格(譯注:“egyptian” 風格又稱 K&R 風格 — 代碼段的開括號位于一行的末尾,而不是另起一行的風格)書寫,左花括號與相應的關鍵詞在同一行上 — 而不是新起一行。左括號前還應該有一個空格,如下所示:

          if (condition) {
            // do this
            // ...and that
            // ...and that
          }

          單行構造(如 if (condition) doSomething())也是一個重要的用例。我們是否應該使用花括號?如果是,那么在哪里?

          下面是這幾種情況的注釋,你可以自己判斷一下它們的可讀性:

          1. 初學者常這樣寫。非常不好!這里不需要花括號:if (n < 0) {alert(`Power ${n} is not supported`);}
          2. 拆分為單獨的行,不帶花括號。永遠不要這樣做,添加新行很容易出錯:if (n < 0) alert(`Power ${n} is not supported`);
          3. 寫成一行,不帶花括號 — 如果短的話,也是可以的:if (n < 0) alert(`Power ${n} is not supported`);
          4. 最好的方式:if (n < 0) { alert(`Power ${n} is not supported`); }

          對于很短的代碼,寫成一行是可以接受的:例如 if (cond) return null。但是代碼塊(最后一個示例)通常更具可讀性。

          三、行的長度

          沒有人喜歡讀一長串代碼,最好將代碼分割一下。

          例如:

          // 回勾引號 ` 允許將字符串拆分為多行
          let str = `
            ECMA International's TC39 is a group of JavaScript developers,
            implementers, academics, and more, collaborating with the community
            to maintain and evolve the definition of JavaScript.
          `;

          對于 if 語句:

          if (
            id === 123 &&
            moonPhase === 'Waning Gibbous' &&
            zodiacSign === 'Libra'
          ) {
            letTheSorceryBegin();
          }

          一行代碼的最大長度應該在團隊層面上達成一致。通常是 80 或 120 個字符。

          四、縮進

          有兩種類型的縮進:

          • 水平方向上的縮進:2 或 4 個空格。一個水平縮進通常由 2 或 4 個空格或者 “Tab” 制表符(key Tab)構成。選擇哪一個方式是一場古老的圣戰。如今空格更普遍一點。選擇空格而不是 tabs 的優點之一是,這允許你做出比 “Tab” 制表符更加靈活的縮進配置。例如,我們可以將參數與左括號對齊,像下面這樣:
          show(parameters,
               aligned, // 5 spaces padding at the left
               one,
               after,
               another
            ) {
            // ...
          }
          • 垂直方向上的縮進:用于將代碼拆分成邏輯塊的空行。即使是單個函數通常也被分割為數個邏輯塊。在下面的示例中,初始化的變量、主循環結構和返回值都被垂直分割了:
          function pow(x, n) {
            let result = 1;
            //              <--
            for (let i = 0; i < n; i++) {
              result *= x;
            }
            //              <--
            return result;
          }


          插入一個額外的空行有助于使代碼更具可讀性。寫代碼時,不應該出現連續超過 9 行都沒有被垂直分割的代碼。

          五、分號

          每一個語句后面都應該有一個分號。即使它可以被跳過。

          有一些編程語言的分號確實是可選的,那些語言中也很少使用分號。但是在 JavaScript 中,極少數情況下,換行符有時不會被解釋為分號,這時代碼就容易出錯。更多內容請參閱 代碼結構 一章的內容。

          如果你是一個有經驗的 JavaScript 程序員,你可以選擇像 StandardJS 這樣的無分號的代碼風格。否則,最好使用分號以避免可能出現的陷阱。大多數開發人員都應該使用分號。

          六、嵌套的層級

          盡量避免代碼嵌套層級過深。

          例如,在循環中,有時候使用 continue 指令以避免額外的嵌套是一個好主意。

          例如,不應該像下面這樣添加嵌套的 if 條件:

          for (let i = 0; i < 10; i++) {
            if (cond) {
              ... // <- 又一層嵌套
            }
          }

          我們可以這樣寫:

          for (let i = 0; i < 10; i++) {
            if (!cond) continue;
            ...  // <- 沒有額外的嵌套
          } //多用這種風格。

          使用 if/elsereturn 也可以做類似的事情。

          例如,下面的兩個結構是相同的。

          第一個:

          function pow(x, n) {
            if (n < 0) {
              alert("Negative 'n' not supported");
            } else {
              let result = 1;
          
              for (let i = 0; i < n; i++) {
                result *= x;
              }
          
              return result;
            }
          }

          第二個:

          function pow(x, n) {
            if (n < 0) {
              alert("Negative 'n' not supported");
              return;
            }
          
            let result = 1;
          
            for (let i = 0; i < n; i++) {
              result *= x;
            }
          
            return result;
          }

          但是第二個更具可讀性,因為 n < 0 這個“特殊情況”在一開始就被處理了。一旦條件通過檢查,代碼執行就可以進入到“主”代碼流,而不需要額外的嵌套。

          七、函數位置

          如果你正在寫幾個“輔助”函數和一些使用它們的代碼,那么有三種方式來組織這些函數。

          1. 在調用這些函數的代碼的 上方 聲明這些函數:
          // function declarations
          function createElement() {
            ...
          }
          
          function setHandler(elem) {
            ...
          }
          
          function walkAround() {
            ...
          }
          
          // the code which uses them
          let elem = createElement();
          setHandler(elem);
          walkAround();
          1. 先寫調用代碼,再寫函數
          // the code which uses the functions
          let elem = createElement();
          setHandler(elem);
          walkAround();
          
          // --- helper functions ---
          function createElement() {
            ...
          }
          
          function setHandler(elem) {
            ...
          }
          
          function walkAround() {
            ...
          }
          1. 混合:在第一次使用一個函數時,對該函數進行聲明。

          大多數情況下,第二種方式更好。

          這是因為閱讀代碼時,我們首先想要知道的是“它做了什么”。如果代碼先行,那么在整個程序的最開始就展示出了這些信息。之后,可能我們就不需要閱讀這些函數了,尤其是它們的名字清晰地展示出了它們的功能的時候。

          八、風格指南

          風格指南包含了“如果編寫”代碼的通用規則,例如:使用哪個引號、用多少空格來縮進、一行代碼最大長度等非常多的細節。

          當團隊中的所有成員都使用相同的風格指南時,代碼看起來將是統一的。無論是團隊中誰寫的,都是一樣的風格。

          當然,一個團隊可以制定他們自己的風格指南,但是沒必要這樣做?,F在已經有了很多制定好的代碼風格指南可供選擇。

          一些受歡迎的選擇:

          • Google JavaScript 風格指南
          • Airbnb JavaScript 風格指南
          • Idiomatic.JS
          • StandardJS
          • 還有很多……

          如果你是一個初學者,你可以從本章中上面的內容開始。然后你可以瀏覽其他風格指南,并選擇一個你最喜歡的。

          九、自動檢查器

          檢查器(Linters)是可以自動檢查代碼樣式,并提出改進建議的工具。

          它們的妙處在于進行代碼風格檢查時,還可以發現一些代碼錯誤,例如變量或函數名中的錯別字。因此,即使你不想堅持某一種特定的代碼風格,我也建議你安裝一個檢查器。

          下面是一些最出名的代碼檢查工具:

          • JSLint — 第一批檢查器之一。
          • JSHint — 比 JSLint 多了更多設置。
          • ESLint — 應該是最新的一個。

          它們都能夠做好代碼檢查。我使用的是 ESLint。

          大多數檢查器都可以與編輯器集成在一起:只需在編輯器中啟用插件并配置代碼風格即可。

          例如,要使用 ESLint 你應該這樣做:

          1. 安裝 Node.JS。
          2. 使用 npm install -g eslint 命令(npm 是一個 JavaScript 包安裝工具)安裝 ESLint。
          3. 在你的 JavaScript 項目的根目錄(包含該項目的所有文件的那個文件夾)創建一個名為 .eslintrc 的配置文件。
          4. 在集成了 ESLint 的編輯器中安裝/啟用插件。大多數編輯器都有這個選項。

          下面是一個 .eslintrc 文件的例子:

          {
            "extends": "eslint:recommended",
            "env": {
              "browser": true,
              "node": true,
              "es6": true
            },
            "rules": {
              "no-console": 0,
              "indent": 2
            }
          }

          這里的 "extends" 指令表示我們是基于 “eslint:recommended” 的設置項而進行設置的。之后,我們制定我們自己的規則。

          你也可以從網上下載風格規則集并進行擴展。有關安裝的更多詳細信息

          此外,某些 IDE 有內置的檢查器,這非常方便,但是不像 ESLint 那樣可自定義。

          十、總結

          本文描述的(和提到的代碼風格指南中的)所有語法規則,都旨在幫助你提高代碼可讀性。它們都是值得商榷的。

          當我們思考如何寫“更好”的代碼的時候,我們應該問自己的問題是:“什么可以讓代碼可讀性更高,更容易被理解?”和“什么可以幫助我們避免錯誤?”這些是我們討論和選擇代碼風格時要牢記的主要原則。

          閱讀流行的代碼風格指南,可以幫助你了解有關代碼風格的變化趨勢和最佳實踐的最新想法。

          為手機備忘錄,好多人再熟悉不過,有些人用它隨手札記,有些人用它記錄秘密,有些人認為根本用不上。可是,這個小小的備忘錄,你真的了解嗎?你知道它隱藏的那些秘密功能嗎?

          1、 速記功能:有個想法,說出來

          想隨時隨地記錄您的重要事項或靈光一閃的金點子,只需說出來。

          在華為手機主界面,屏幕解鎖狀態下,從屏幕邊緣的速記區域向內滑動。即可打開備忘錄"速記"功能,可以通過語音、文字或照片方式迅速創建筆記或者創建待辦。并且,備忘錄會將語音轉換為文字,并同時記錄語音和文字。

          速記gif

          設置方法:打開備忘錄,選擇左上角圖標"?"> 設置 > 速記,打開速記開關。在提示界面打開在其他應用上層顯示,并設置入口位置為屏幕左側或屏幕右側。

          二、待辦管理:它提醒您,誤不了

          情人節那天,因為備忘錄的提醒,我沒有忘記買禮物。

          重要事項,卻總擔心忘了,可以讓備忘錄幫你記住。備忘錄支持語音錄入待辦事項,提醒方式有指定時間和指定位置。

          *指定位置:當經過設置的目的地有效范圍并超過1分鐘時,鬧鐘會提醒。

          操作方法:全部待辦列表界面輸入待辦事項后,點擊

          添加提醒,設置指定時間/智能位置

          三、手寫涂鴉:畫出來,更生動

          文字表達不清楚,寥寥幾筆的繪畫可能更生動形象,備忘錄也可以變身畫板。

          除了速記助手,手寫涂鴉也讓人相見恨晚。打開備忘錄并進入編輯筆記模式。除了語音、文字和圖片三種方式,還可進行涂鴉。無論是文檔注釋還是繪畫創意,都可以肆意書寫。

          操作方法:選擇筆記 >

          ,點擊

          ,手寫您要記錄的內容。

          四、速記分享:一鍵分享,簡單

          想把備忘錄里的內容發個朋友圈,可以輕松一鍵分享。

          速記的內容保存為筆記后,可以一鍵分享到微博、微信,精彩內容傳遞更便捷。

          操作方法:全部筆記全部待辦列表界面,打開要分享的備忘錄,點擊

          ,按屏幕提示完成分享。

          五、更貼心:誤刪了,沒關系

          1.最近刪除:挽回誤刪事項

          一不小心刪掉的筆記和待辦事項,沒關系!可以在"最近刪除"中找到并恢復。多一重保障,多一份安心。

          2..多端同步:備忘內容不丟失

          支持多設備數據同步,通過華為賬號,隨時隨地查看和編輯你的備忘錄信息。

          HUAWEI P30 系列手機上,有AI注入的備忘錄,就像擁有靈魂一般,它所能做的與過去相比,已經不可同日而語,讓我們感受一下這小小的身軀里那些大大的能量吧。

          *不同機型對上述功能的支持情況各有差異,請以手機實際為準。

          發現更多精彩功能請下滑主屏幕,搜索"玩機技巧"應用

          HUAWEI P30 系列新品開售,點擊以下圖片立即擁有!

          移動端跳轉鏈接:

          PC端跳轉鏈接:https://www.vmall.com/product/10086501288078.html?cid=90002

          里有一些我最喜歡的關于編寫更簡潔的 Javascript 代碼的技巧。

          1.忘掉var

          使用constlet聲明所有變量。根據經驗,默認情況下使用const,否則如果需要重新分配變量,則使用let

          應避免使用var關鍵字,因為它幾乎不受作用域限制導致潛在的作用域錯誤,請參閱我的提升指南。

          好處:最佳實踐是在創建變量時初始化變量,這樣您和您的團隊就可以確保沒有變量被閑置。

          // ? Avoid this
          var old = "";
          
          // ? Do this
          const immutable = "John";
          let counter = 1;
          counter++; // counter === 2;
          
          // Declare objects and arrays as const to prevent type change
          const user = {firstname: "John", lastname: "Doe"};
          const users = ["Mac", "Roe"];
          

          2、使用嚴格相等(===)

          嚴格相等運算符(===)與相等運算符相同,檢查兩個操作數是否相等,并返回布爾結果。但與相等運算符 ( == )不同,嚴格相等運算符(===)始終認為不同類型的操作數是不同的。

          好處:在非嚴格相等運算符的情況下,0 為假將錯誤地等于假。

          // ? Avoid this
          1 == "1"; // true
          0 == false; // true
          
          // ? Do this
          1 === 1; // true
          1 === "1"; // false
          0 === false; // false
          

          3. 避免使用原始對象的構造函數

          原始對象與其原始對象完全不同,這使得它們在包裝在對象中時更難以檢查嚴格相等性。

          它們基本上是等價的,但不相等。

          // ? Avoid this
          const stringObject = new String("Charly");
          
          // ? Do this
          const stringPrimitive = "Charly";
          
          // Equality check
          stringPrimitive === stringObject; // false 
          new Number(1) === 1; // false
          new Boolean(true) === true; // false
          

          4. 使用對象文字

          對象字面量是一種速記符號,允許您動態定義對象或數組。

          從而避免重復,提高可讀性并防止錯誤,因為我們無法推斷其背后的邏輯,我們當前是在初始化變量還是更新它?

          // ? Avoid this
          const user = new Object(); // {}
          user.firstname = "John"; // { firstname: "John" }
          user.lastname = "Doe"; // { firstname: "John", lastname: "Doe" }
          
          // ? Do this
          const user = { 
            firstname: "John", 
            lastname: "Doe" 
          };
          
          // ? Avoid this
          const fruits = new Array(); // []
          fruits.push("banana"); // ["banana"]
          fruits.push("mango"); // ["banana", "mango"]
          
          // ? Do this
          const fruits = ["banana", "mango"];
          

          5. 使用模板文字來組合字符串

          將字符串放在一起是一件痛苦的事情,尤其是在組合字符串和變量時。

          為了使這個過程更簡單,您可以使用模板文字(用反引號標記),它同時接受字符串變量,只要它被插值(${})包圍即可。

          const firstname = "John";
          
          // ? Avoid this
          let greeting = "Hello, " + firstname; // Hello, John
          
          // ? Do this
          greeting = `Hello, ${firstname}`; // Hello, John
          

          6. 使用分號作為行終止符

          使用分號作為行終止始終是一個好習慣。

          如果您忘記了它,則不會收到警告,因為在大多數情況下它將由 JavaScript 解析器插入。但如果沒有它,你怎么知道表達式何時結束呢?

          以for循環為例:

          // ? Do this
          for (let i = 0; i < numbers.length; i++) {
            console.log(numbers[i]);
          }
          

          您將無法執行以下操作,因為解析器認為它是一個表達式,而實際上它是三個獨立的表達式:

          // ? Not this
          for (let i = 0 i < numbers.length i++) {
            console.log(numbers[i]);
          } // Uncaught SyntaxError: Unexpected identifier
          

          7. 使用對象參數代替多個參數

          我認為在函數中定義太多參數是一種f壞代碼味道。即使參數有默認值或者是可選的,我們還是以這個例子為例:

          // ? Avoid this
          function avatarUrl(avatar, format = "small", caption = true) {
            // Does something
          }
          
          avatarUrl(user.avatar, 'thumb', false)
          

          當您使用此函數時,很難知道使用了哪些參數以及如何使用。最后一個參數false在這里代表什么?

          不知道,我們必須打開函數定義才能知道。
          如果您需要更改參數的順序會發生什么?那么您必須更改所有函數調用。

          對于對象來說,順序并不重要:

          // ? Do this
          function avatarUrl(avatar, options={format: 'small', caption: true}) {
            // Does something
          }
          
          avatarUrl(user.avatar, {
            format: "thumb", 
            caption: false
          })
          

          8.盡早返回

          嵌套條件使代碼難以理解,但您可以通過提前返回來使用保護子句輕松避免它。

          保護子句將允許您刪除大部分 else 條件,使您的代碼像簡單的英語一樣可讀。

          // ? Avoid this
          function doSomething() {
            if (user) {
              if (user.role === "ADMIN") {
                return 'Administrator';
              } else {
                return 'User';
              }
            } else {
              return 'Anonymous';
            }
          }
          
          // ? Do this
          function doSomething() {
            if (!user) return 'Anonymous'
            if (user.role === "ADMIN") return 'Administrator'
          
            return 'User'
          }
          

          9.學習并使用內置函數的力量

          Javascript 在ArrayObject、String上提供了很多內置函數。

          找到并學習它們,以充分發揮堆棧的威力。

          // ? Avoid this
          const users = [
            {
              username: "JohnDoe",
              admin: false
            },
            {
              username: "Todd",
              admin: true
            },
          ];
          const admins = [];
          
          function getAdmins() {
            users.forEach((user) => {
              if (user.admin) admins.push(user)
            })
          
            return admins
          }
          
          // ? Do this
          function getAdmins() {
            return users.filter((user) => user.admin)
          }
          

          10. 代碼是為人類編寫的,而不是為計算機編寫的

          讓我們假設,我們大多數人都不善于注意到差異,我們可能需要幾秒鐘才能注意到邏輯上的 not (!)。

          讓我們看這個例子:

          const users = [
            {
              username: "JohnDoe",
              admin: false
              enabled: true
            },
            {
              username: "Todd",
              admin: true
              enabled: true
            },
          ];
          
          // ? Avoid this
          const members = users.filter(u => u.enabled).map(u => !u.admin)
          const admins = users.filter(u => u.enabled).map(u => u.admin)
          
          // ? Do this
          const enabledUsers = users.filter(u => u.enabled)
          const members = enabledUsers.map(u => !u.admin)
          const admins = enabledUsers.map(u => u.admin)
          

          成員和管理員分配的區別僅在于邏輯非 (!),如果您需要更改一項分配,那么您還需要更改另一項分配。

          另一個例子,不要使用幻數。使用顯式變量代替:

          // ? Avoid this
          function price_with_taxes(price) {
            return price * 1.2
          }
          
          // ? Do this
          const taxRate = 1.2
          function price_with_taxes(price) {
            return price * taxRate
          }
          

          11.避免縮寫

          無論您將“e”寫為“event”,還是將“t”寫為“ticket”,都不會提高您的工作效率,但會降低可讀性并降低即時理解能力。

          // ? Avoid this
          function someFunction() {
            events.forEach(e => {
              e.tickets.forEach(t => {
                `${e.name} for ${t.full_name}`
              })
            })
          }
          
          // ? Do this
          function someFunction() {
            events.forEach(event => {
              event.tickets.forEach(ticket => {
                `${event.name} for ${ticket.full_name}`
              })
            })
          }
          

          在這里你不必猜測 e 和 t 代表什么,你只需閱讀即可。
          編碼非常復雜,額外的復雜性足以讓您感到臃腫。這也適用于變量、類、方法......

          但也有少數例外,在 for 循環中使用廣泛使用的縮寫(如 i)是可以的。

          12.避免無用的&&否定條件

          條件就像大腦的備忘錄,因為您需要在逐步執行每一行代碼時記住它們,以便了解發生了什么。

          幸運的是,由于我最喜歡的 ES6 操作符可選鏈接,其中大多數都可以得到簡化。

          // ? Avoid this
          function doSomething(params) {
            if (params && params.filter) return 'Foo'
          
            return 'Bar'
          }
          
          // ? Do this
          function doSomething(params) {
            if (params?.filter) return 'Foo'
          
            return 'Bar'
          }
          

          我不了解你,但每次我看到邏輯不(!)時,我的大腦都會暫停一秒鐘,對我來說,讀到這樣的內容感覺更自然:

          如果用戶是管理員那么我們就這樣做

          而不是:

          如果用戶不是管理員,那么我們就會這樣做。

          // ? Avoid this
          function doSomething(user) {
            if (!user || !user.admin) {
              // Case where no user or not admin
            } else {
              // Case where user and user is admin
            }
          }
          
          // ? Do this
          function doSomething(user) {
            if (user && user.admin) {
              // Case where user and user is admin
            } else {
              // Case where no user or not admin
            }
          }
          

          13.使用for...of代替for循環

          使用for...of語句代替經典的for 循環就是 JavaScript 的一項改進。

          這個語法是 ES6 引入的,它包含一個內置的迭代器,這樣你就不必定義自己的變量,將其遞增直到某個長度值:

          let users = ["Fedor Emelianenko", "Cyril Gane", "Conor McGregor"];
          
          // ? Avoid this
          // This avoids length behind reavaluated at every iteration
          let usersCount = users.length;
          for (let i = 0; i < usersCount; i++) {
              console.log(users[i]);
          }
          
          // ? Do this
          for(let user of users) {
              console.log(users);
          }
          

          請注意它的可讀性有多強!而且您不必關心所有這些 (let i = 0; i < usersCount; i++) 笨拙的邏輯,盡管您可能需要它用于某些特定的用例,例如不規則的間隔。

          14. 可讀的代碼勝過聰明的代碼

          永遠記住,您正在與其他開發人員以及未來的自己一起編寫代碼。您不想制造比編寫代碼要解決的問題更多的問題。

          不要編寫代碼來炫耀你的技能,編寫每個人都可以理解和調試的代碼。

          如果您有更多提示,我很樂意在評論中向您學習!

          把事情簡單化!


          主站蜘蛛池模板: 亚洲日韩精品一区二区三区 | 无码精品人妻一区二区三区AV| 亚洲欧美成人一区二区三区 | 国产波霸爆乳一区二区| 黑巨人与欧美精品一区| 日韩欧国产精品一区综合无码| 人成精品视频三区二区一区| 亚洲A∨精品一区二区三区下载| 亚洲AV无码一区二区三区系列| 一本岛一区在线观看不卡| 尤物精品视频一区二区三区| 2018高清国产一区二区三区| 亚洲爆乳无码一区二区三区| 在线观看午夜亚洲一区| 波多野结衣一区二区三区aV高清| 成人国产精品一区二区网站公司| 亚洲欧洲日韩国产一区二区三区 | 成人H动漫精品一区二区| 免费一本色道久久一区| 色狠狠色狠狠综合一区| 国产精品香蕉在线一区| 精品国产AV一区二区三区| 久久精品一区二区三区日韩| 久久精品一区二区| 无码人妻少妇色欲AV一区二区 | 亚洲一区精彩视频| 久久久国产精品无码一区二区三区| 国产精品一区二区久久| 亚洲AV一区二区三区四区| 国产小仙女视频一区二区三区| 国产乱码精品一区二区三区麻豆| 国模大胆一区二区三区| 国产在线无码视频一区| 日本高清天码一区在线播放| 国产一区二区三区免费在线观看 | 国产在线不卡一区二区三区| 国产亚洲福利精品一区| 97久久精品无码一区二区天美 | 国产一区二区三区在线观看免费| 亚洲国产一区二区视频网站| 精品免费久久久久国产一区|