核心要點
創建方法也意味著編寫 API——無論是為您自己、團隊中的其他開發人員還是使用您項目的其他開發人員。根據函數的大小、複雜性和用途,您必須考慮默認設置和輸入/輸出的 API。默認函數參數和屬性簡寫是 ES6 的兩個方便的功能,可以幫助您編寫 API。
ES6 默認參數
讓我們快速回顧一下知識,再看看語法。默認參數允許我們為函數初始化默認值。當參數被省略或未定義時使用默認值——這意味著 null 是一個有效值。默認參數可以是任何東西,從數字到另一個函數。
// 基本语法 function multiply(a, b = 2) { return a * b; } multiply(5); // 10 // 默认参数也适用于后面的默认参数 function foo(num = 1, multi = multiply(num)) { return [num, multi]; } foo(); // [1, 2] foo(6); // [6, 12]
讓我們來看一個基本函數,並演示默認參數如何加快您的開發速度並使代碼組織得更好。我們的示例方法稱為 createElement()。它接受一些配置參數,並返回一個 HTML 元素。 API 看起來像這樣:
// 我们想要一个 <p> 元素,带有一些文本内容和两个附加的类。 // 返回 <p>Such unique text</p> createElement('p', { content: 'Such unique text', classNames: ['very-special-text', 'super-big'] }); // 为了使此方法更有用,它应该在任何参数被省略或根本没有传递参数时始终返回默认元素。 createElement(); // <div>Very default</div>
此方法的實現不會有很多邏輯,但由於其默認覆蓋範圍,它可能會變得相當大。
// 没有默认参数,它看起来相当臃肿且不必要地庞大。 function createElement(tag, config) { tag = tag || 'div'; config = config || {}; const element = document.createElement(tag); const content = config.content || 'Very default'; const text = document.createTextNode(content); let classNames = config.classNames; if (classNames === undefined) { classNames = ['module-text', 'default']; } element.classList.add(...classNames); element.appendChild(text); return element; }
到目前為止,一切順利。這裡發生了什麼?我們正在執行以下操作:
現在讓我們使用此函數並對其進行優化,使其更簡潔、編寫速度更快,並且更清晰地表明其用途:
// 基本语法 function multiply(a, b = 2) { return a * b; } multiply(5); // 10 // 默认参数也适用于后面的默认参数 function foo(num = 1, multi = multiply(num)) { return [num, multi]; } foo(); // [1, 2] foo(6); // [6, 12]
我們沒有觸及函數的邏輯,而是從函數體中刪除了所有默認處理。函數簽名現在包含所有默認值。讓我進一步解釋一部分,這可能有點令人困惑:
// 我们想要一个 <p> 元素,带有一些文本内容和两个附加的类。 // 返回 <p>Such unique text</p> createElement('p', { content: 'Such unique text', classNames: ['very-special-text', 'super-big'] }); // 为了使此方法更有用,它应该在任何参数被省略或根本没有传递参数时始终返回默认元素。 createElement(); // <div>Very default</div>
我們不僅聲明了一個默認對象參數,還聲明了默認對象屬性。這使得默認配置看起來更清晰,而不是只聲明一個默認對象(例如 config = {})然後稍後設置默認屬性。可能需要一些額外的時間來適應它,但最終它會改善您的工作流程。當然,對於更大的配置,我們仍然可以爭論說它可能會創建更多開銷,並且只需將默認處理保留在函數體中會更簡單。
ES6 屬性簡寫
如果方法接受大型配置對像作為參數,則您的代碼可能會變得相當大。通常的做法是準備一些變量並將它們添加到該對像中。屬性簡寫是語法糖,可以使此步驟更短、更易讀:
// 没有默认参数,它看起来相当臃肿且不必要地庞大。 function createElement(tag, config) { tag = tag || 'div'; config = config || {}; const element = document.createElement(tag); const content = config.content || 'Very default'; const text = document.createTextNode(content); let classNames = config.classNames; if (classNames === undefined) { classNames = ['module-text', 'default']; } element.classList.add(...classNames); element.appendChild(text); return element; }
好的,讓我們回到另一個更常見的例子。以下函數獲取一些數據,對其進行修改並調用另一個方法:
// 默认所有内容 function createElement(tag = 'div', { content = 'Very default', classNames = ['module-text', 'special'] } = {}) { const element = document.createElement(tag); const text = document.createTextNode(content); element.classList.add(...classNames); element.appendChild(text); return element; }
我們經常會將變量和對象屬性名稱命名為相同。使用屬性簡寫結合解構,我們實際上可以縮短代碼很多:
// 这里到底发生了什么? function createElement({ content = 'Very default', classNames = ['module-text', 'special'] } = {}) { // 函数体 }
同樣,這可能需要一段時間才能適應。最終,它是 JavaScript 中的新功能之一,它幫助我更快地編寫代碼並使用更簡潔的函數體。但是等等,還有更多!屬性簡寫還可以應用於對象內的使用方法定義:
const a = 'foo', b = 42, c = function() {}; // 以前我们会像这样使用这些常量。 const alphabet = { a: a, b: b, c: c }; // 但是使用新的简写,我们现在实际上可以这样做, // 这与上面相同。 const alphabet = {a, b, c};
結論
默認參數和屬性簡寫是使您的方法更井然有序,在某些情況下甚至更短的好方法。總的來說,默認函數參數幫助我更專注於方法的實際用途,而不會因大量的默認准備工作和 if 語句而分心。屬性簡寫確實更多的是一種外觀上的特性,但我發現自己生產力更高,並且花費更少的時間來編寫所有變量、配置對象和函數關鍵字。您是否已經在使用默認參數和屬性簡寫? 本文由 Sebastian Seitz 進行了同行評審。感謝所有 SitePoint 的同行評審者,使 SitePoint 內容盡善盡美!
關於 ES6 默認參數的常見問題 (FAQ)
ES6 默認參數提供了多個優勢。首先,它們有助於使您的代碼更簡潔易讀。無需檢查參數是否未定義,然後分配默認值,您可以在一行中完成所有操作。這減少了您必須編寫的代碼量,並使其他人更容易理解您的代碼。其次,它們有助於防止錯誤。如果函數期望某個參數但未提供,則可能導致意外結果或錯誤。通過設置默認參數,您可以確保您的函數擁有其正常工作所需的所有參數。
是的,您可以將 ES6 默認參數與解構賦值一起使用。這是 ES6 的一個強大功能,它允許您將數組中的值或對像中的屬性解包到不同的變量中。與默認參數結合使用時,您可以從對像或數組中提取值,並在提取的值未定義時分配默認值。
arguments 對像是一個類似數組的對象,其中包含傳遞給函數的所有參數。但是,它並非擁有數組的所有方法,並且不如 ES6 默認參數功能靈活。使用默認參數,您可以為任何未定義的參數設置默認值,而這在 arguments 對像中是不可能的。
是的,您可以在構造函數中使用 ES6 默認參數。在創建類的新的實例時,這尤其有用。如果在創建新實例時未提供某些參數,則將使用默認參數,以確保新對象具有所有必要的屬性。
一般來說,使用 ES6 默認參數的性能影響很小,不應成為問題。但是,像任何功能一樣,應該謹慎使用它。過度使用默認參數,尤其是在性能關鍵的代碼中,可能會導致執行時間變慢。與往常一樣,務必測試您的代碼並監控其性能。
是的,您可以將 ES6 默認參數與箭頭函數一起使用。 ES6 中引入的箭頭函數提供了一種簡潔的語法來編寫函數表達式。在使用將其他函數作為參數的高階函數時,它們尤其有用。
如果參數傳遞了 null 值,則 ES6 默認參數功能將不會分配默認值。這是因為 null 在 JavaScript 中被認為是一個值,與 undefined 不同。如果要在參數為 null 時分配默認值,則需要在代碼中單獨處理這種情況。
是的,您可以在遞歸函數中使用 ES6 默認參數。當您想要為遞歸函數提供基本情況但又不想要求調用者始終提供它時,這尤其有用。
是的,您可以將 ES6 默認參數與剩餘參數一起使用。但是,請記住,剩餘參數必須是函數定義中的最後一個參數。此外,您不能為剩餘參數本身分配默認值,但可以為剩餘參數的一部分的各個參數分配默認值。
是的,您可以將 ES6 默認參數與擴展運算符一起使用。擴展運算符允許您將可迭代對象(如數組)擴展為各個元素。與默認參數結合使用時,您可以將一組值傳遞給函數,並為任何未定義的參數分配默認值。
以上是帶有ES6默認參數和屬性速記的清潔代碼的詳細內容。更多資訊請關注PHP中文網其他相關文章!