iT邦幫忙

2024 iThome 鐵人賽

DAY 18
1
IT 管理

30天從版控到code review的實踐指南系列 第 18

Day 18. Code Review 程式碼風格-規則篇

  • 分享至 

  • xImage
  •  

接下來四天的內容將會圍繞於程式碼風格規範的討論,並透過實作 ESLint 與 Prettier 來提升程式碼整潔度。最後,將提供 Code Review 的範例,實際應用這些規範。規範的目的是為了強化團隊協作,讓程式碼更容易維護和重構,同時提升專案的可持續性。

本篇將介紹程式碼風格規則,以 JavaScript 為例:

變數規則:


  1. 命名習慣:

    使用駝峰式命名法(camelCase)來命名變數:

    let userAge;
    

    常量使用全大寫,並以底線分隔單詞(UPPER_CASE):

    const MAX_RETRIES = 5;
    

    避免使用單字母變數名稱(除非用在迴圈如 i、j):

    let index = 0;
    
  2. 宣告方式:優先使用 const,如果變數需要重新賦值則使用 let,避免使用 var。

    const apiUrl = 'https://api.example.com';
    let retryCount = 3;
    
  3. 變數範圍控制:儘量減少全域變數,將變數宣告在最小必要範圍內(區域範圍)。

  4. 變數初始化:

    宣告變數時,同時初始化:

    let isLoggedIn = false;
    
  5. 變數排序:

    將變數按照類型和用途有邏輯地分組:

    const classmateName = 'John';
    const age = 30;
    let totalScore = 0;
    let isLoggedIn = false;
    

函數規則


  1. 命名習慣:

    函數名稱應該描述其功能,且通常以動詞開頭:

    function calculateTotal() { ... }
    const fetchData = () => { ... };
    
  2. 箭頭函數:

    優先使用箭頭函數作為匿名函數:

    const multiply = (a, b) => a * b;
    
  3. 單一職責:

    每個函數應只完成單一任務。避免函數過長,若有需要則將其分割成小函數:

    function saveUser(user) {
      validateUser(user);
      storeUser(user);
    }
    
  4. 參數數量控制:

    函數參數應儘量控制在 3 個以內,若需要傳遞多個參數,使用物件:

    function createUserInfo({ name, age, email }) { ... }
    
  5. 避免過早的 return :

    // 過早 return:
    function checkUser(user) {
      if (!user) {
        return false;
      }
      if (!user.isActive) {
        return false;
      }
      return true;
    }
    
    // 簡潔寫法
    function checkUser(user) {
      return user && user.isActive;
    }
    

一般風格規則


  1. 一致的縮排:

    使用 2 或 4 個空格作為縮排,且保持一致。

  2. 引號風格:

    優先使用單引號 ' ' 來表示字串:

    const message = 'Hello, world!';
    
  3. 分號:

    明確地在每一行結束處使用分號:

    let age = 30;
    console.log(age);
    
  4. 大括號風格:

    使用 K&R 樣式的大括號, { 與條件語句在同一行:

    if (isValid) {
      console.log('Valid!');
    }
    
  5. 移除未使用的變數和函數,保持程式碼簡潔。

  6. 使用一致的命名方式,避免縮寫和模糊的變數/函數名稱。

Summary


透過這些 JavaScript 程式碼風格規則,可以維持程式碼的一致性和可讀性,並讓團隊協作更加順暢。結合 ESLint 和 Prettier 可以自動化這些規範,確保在開發過程中遵循統一的標準。

Js 小教室:箭頭匿名函數 v.s 傳統匿名函數

  • 匿名函數:指沒有名稱的函數,一般作為參數傳遞給其他函數,或作為即時函數使用。使用情境:通常在需要執行一次性任務時使用。
  • 為何優先使用箭頭函數?

  1. 簡潔的語法:

    傳統函數:

        const numbers = [1, 2, 3];
        const doubled = numbers.map(function(num) {
          return num * 2;
        });
        ```
    
     箭頭函數:
    
        ```jsx
        const numbers = [1, 2, 3];
        const doubled = numbers.map(num => num * 2);
        ```
    
  2. this 的綁定:
    箭頭函數不會重新綁定 this,會從外層 Scope 繼承 this。避免在傳統匿名函數中 this 綁定錯誤的常見問題。
    傳統函數 this 問題:

     ```jsx
     function timer() {
       this.seconds = 0;
       setInterval(function() {
         this.seconds++;
         console.log(this.seconds); // this 指向全域物件 (window)
       }, 1000);
     }
     const timer = new Timer();  // 導致 this.seconds 是 undefined
     ```
    
     箭頭函數解決 this 問題:
    
     ```jsx
     function timer() {
       this.seconds = 0;
       setInterval(() => {
         this.seconds++;
         console.log(this.seconds); // this 指向 timer 物件本身
       }, 1000);
     }
     const timer = new Timer();  // this.seconds 會正常增加
     ```
    
  3. 更具可讀性:
    使用箭頭函數可以讓程式碼看起來更乾淨且易讀。例如,在 return 函數或高階函數(Higher Order Function),例如:map、filter、reduce 中,箭頭函數顯得更加直觀。

    範例 1:在 return 函數中使用


    const numbers = [1, 2, 3, 4];
    
    // 傳統函數
    const squares = numbers.map(function(num) {
      return num * num;
    });
    
    // 箭頭函數
    const squaresArrow = numbers.map(num => num * num);
    

    範例 2:在 Promise 中使用


    // 傳統匿名函數
    new Promise(function(resolve, reject) {
      resolve('Success');
    }).then(function(result) {
      console.log(result);
    });
    
    // 箭頭函數
    new Promise((resolve, reject) => {
      resolve('Success');
    }).then(result => {
      console.log(result);
    });
    

    範例 3:在事件處理器中使用


    const myObject = {
      name: "My Object",
      init: function() {
        $('.button').on('click', (event) => {
          // 使用 event.currentTarget 來指向觸發事件的按鈕
          $(event.currentTarget).text('Clicked!'); // 這裡正確指向 button 元素
          console.log(this.name); // 輸出 "My Object"(指向外層 Scope)
        });
      }
    };
    
    myObject.init();
    

上一篇
Day.17 Code Review:功能邏輯-下篇
下一篇
Day 19. Code Review 程式碼風格-Prettier 輔助工具篇
系列文
30天從版控到code review的實踐指南30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言