1. 程式人生 > 程式設計 >JavaScript基礎系列之函式和方法詳解

JavaScript基礎系列之函式和方法詳解

目錄
  • 一、函式和方法的區別
  • 二、如何寫好一個函式
    • 2.1 命名準確
      • 2.1.1 函式命名
      • 2.1.2 引數命名
    • 2.2 函式註釋
      • 2.2.1 引數註釋
    • 2.3 函式引數
      • 2.3.1 引數預設值
      • 2.3.2 物件引數
      • 2.3.3 引數數量
      • 2.3.4 引數型別防禦
    • 2.4 函式的返回
      • 2.4.1 冪等函式
      • 2.4.2 純函式
      • 2.4.3 return null
  • 函式和方法的區別
    • 總結

      一、函式和方法的區別

      • 函式(function):函式是帶有名稱和引數的 程式碼段,可以一次定義多次呼叫。
      • 方法(method):當將函式和物件寫在一起時,函式就變成了“方法”,比如當函式賦值給物件的屬性時,我們便稱其為“方法”。

      二、如何寫好一個函式

      在 中,除了變數,用的最多的應該就是函數了,函式是 script 的第一公民。

      2.1 命名準確

      2.1.1 函式命名

      函式的命名需要明確,語義清晰,簡單概括函式的功能。我們不要想著程式碼簡短而縮短函式名稱,這並不會提高什麼效能或效率,相反,一個函式名稱若不夠清晰,往往其他人無法理解。

      儘量使用動詞,比如:getXxxxx、setXxxxx,動詞在前面,語義就能更加清晰。

      2.1.2 引數命名

      強調語義化,引數命名讓呼叫者更清晰的知道該傳入什麼,對應什麼引數。當然,像一些通用命名還是可接受的,像 callback,fn,即使不看註釋,往往我也知道這裡的引數要做什麼,傳什麼。

      2.2 函式註釋

      /**
       * 時間格式化工具函式
       * 
       * @param { (Date | number) } date - 時間
       * @param { string } unit - 轉換格式
       */
      export const timeFormat = (date: Date | number | string,unit: string) => {
        if (!date) {
          return ''
        }
        if (typeof date === 'string') return date;
        if (typeof date === 'number') {
          date = new Date(date);
        }
        const year = date.getFullYear();
        const month = date.getMonth() + 1;
        const day = date.getDate();
        const hour = date.getHours();
        const minute = date.getMinutes();
        const second = date.getSeconds();
        if (unit === 'year') return `${year}`;
        if (unit === 'month') return `${year}-${month}`;
        if (unit === 'day') return `${year}-${month}-${day}`;
        if (unit === 'hour') return `${year}-${month}-${day} ${hour}`;
        if (unit === 'minute') return `${year}-${month}-${day} ${hour}:${minute}`;
        if (unit === 'swww.cppcns.com
      econd') return `${year}-${month}-${day} ${hour}:${minute}:${second}`; }

      2.2.1 引數註釋

      /**
       * 時間格式化工具函式
       * 
       * @param { (Date | number) } date - 時間
       * @param { string } unit - 轉換格式
       */
      

      @param { type } 引數 - 引數解釋:type 表明的是引數的型別,比如 string,number,當有多個引數型別的時候,可以這麼來標識 { (string|string[]) },表示這個引數可以是字串或者字串陣列。

      物件屬性:需要解釋物件的http://www.cppcns.com每一個屬性

      /**
       * 將專案分配給員工的函式
       * 
       * @param {Object} employee - 專案員工
       * @param {string} employee.name - 專案員工的姓名
       * @param {string} employee.department - 專案員工的部門
       */
       Project.prototype.assign = function(employee) {
         // ...
       };
      

      可選引數:

      /**
       * 時間格式化工具函式
       * 
       * @param { (Date | number | string) } date - 時間
       * @param { string } [unit] - 轉換格式
       */
      export const timeFormat = (date: Date | number | string,unit: string) => {
        // ...
      }
      

      預設值:

      /**
       * 時間格式化工具函式
       * 
       * @param { (Date | number) } date - 時間
       * @param { string } [unit = 'second'] - 轉換格式
       */
      export const timeFormat = (date: Date | number | string,unit = 'second') => {
        // ...
      }
      

      2.3 函式引數

      2.3.1 引數預設值

      export const timeFormat = (date: Date,unit = 'second') => {
        // ...
      }
      

      2.3.2 物件引數

      async function printer_proxy_print(
        html_str: string,file_path: string,device: string | undefined,orientation: number,printer_mode: string,width: number,height: number,scale: number,from: number,to: number,left_offset: number,top_offset: number,pdf_tools: string | undefined,begin_page = 1,end_page = 1,repeat_times = 1,print_type: string
      ) {
          // ...
      }
      

      可以給引數預設值,這樣可以只傳前面幾個必要的引數,像這樣呼叫。

      async function printer_proxy_print(
        html_str: string,device = 'pc',orientation = 'xxx',printer_mode = 'xxx',width = 123,height = 123,scale = 123,from = 123,to = 123,left_offset = 123,top_offset = 123,pdf_tools = 123,print_type = 'base64'
      ) {
          // ...
      }
      
      await printer_proxy_print(html_str,file_path);
      

      上面的方法看似可行,實際上,當我中間某個引數不一樣的時候,我就需要把這個引數前面的引數都傳一遍。這樣顯然不可行。所以當引數多的時候,我們需要用物件解構的方式傳參。

      async function printer_proxy_print({
        html_str,file_path,print_type = 'base64'
      }) {
          // ...
      }
      
      await printer_proxy_print({html_str,file_path});
      

      解構的好處便是我可以隨便傳我想要的某幾個引數,而不用在意順序問題。不過像這麼多引數的函式往往存在問題(具體問題具體分析)。也就是下面提到的引數數量問題。

      2.3.3 引數數量

      一個函式的引數越少越好,最多不應該超過3個,引數多往往意味著關係多,邏輯交叉相對也就多了起來。在進行測試的時候,往往也就很難覆蓋到所有條件,出問題概率也就加大了。

      引數多的時候,有時候也意味著功能多,就違背了 單一功能 的原則。

      2.3.4 引數型別防禦

      在 TS 開發前,我們不知道使用者會傳什麼東西進來,這時候往往容易產生型別錯誤,又或者,我們想實現相容,像前面的 timeFormat 函式,我們希望使用者呼叫的時候,可以是想對 時間物件 格式化,也可以是對 時間戳 格式化,那我們就需要做一個防禦處理。

        if (!date) {
          return ''
        }
        if (typeof date === 'string') return date;
        if (typewww.cppcns.comof date === 'number') {
          date = new Date(date);
        }
      

      不過值得注意的是,即使我們用上了 TS,在大多數情況下,我們確實可以避免參數型別問題,但是這並不絕對,因為我們有時候會直接接受 介面 返回的資料。

      我們常說,永遠不要相信使用者的輸入,同樣,介面返回的資料我也不信,我們不能保證,後端不會出錯,約定好的引數是陣列型別,怎麼空的時候,你給我個 null 呢?

      當然這些情況有時候需要去試錯,有時候我們能想到的可能,不要偷懶,給寫上型別判斷吧。

      2.4 函式的返回

      2.4.1 冪等函式

      什麼叫冪等,簡單來說,輸入什麼輸http://www.cppcns.com出什麼是固定的,入參決定了出參,不管呼叫多少次,只要輸入一樣,結果應該保持一樣。

        function sum(a: number,b: number) {
          return a + b;
        }
      

      冪等函式具有可維護性,相對容易進行單元測試。

      2.4.2 純函式

      純函式在冪等的條件下,還要求沒有副作用。

        const dog = {
          name: 'puppy',age: 2,weight: 30,}
      
        if (!dog.color) {
          console.log('has no color');
        }
      
        function addColor(dog) {
          dog.color = 'white';
        }
      
        addColor(dog);
        console.log(dog); // {name: "puppy",color: "white"}
      

      可以看到,addColor 函式修改了 dog 物件的屬性,也就是產生了副作用。

        function addColor(dog) {
          let copyDog = Object.assign({},dog);
          copyDog.color = 'white';
          return copyDog;
        }
      

      這樣一來,dog 物件的屬性就不會修改,addColor 函式是純函式。

      2.4.3 return null

      null 在進行處理的時候相對麻煩,需要進行判斷,導致了額外的程式碼,應當返回空物件,或者是空陣列,或者丟擲異常。

      函式和方法的區別

      1)函式(function)是一段程式碼,通過名字來進行呼叫。它能將一些資料(引數)傳遞進去進行處理,然後返回一些資料(返回值),也可以沒有返回值。

      2)方法(method)是通過物件呼叫的javascript函式。也就是說,方法也是函式,只是比較特殊的函式。他是和一個物件相關聯。假設有一個函式是fn,一個物件是obj,那麼就可以定義一個method:

      obj.method = fn;
      obj.method();

      3)函式的資料是顯式傳遞

      4)方法中的資料是隱式傳遞的;方法和物件相關。

      總結

      到此這篇關於JavaScript基礎系列之函式和方法的文章就介紹到這了,更多相關JavaScript函式和方法內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!