🔍 搜尋結果:console

🔍 搜尋結果:console

寫出更好 JavaScript 的幾個實務技巧:新手推薦

JavaScript 寫起來有很大彈性,但如何改善自己的 JavaScript 品質呢?以下是一份實用的參考指南。 - 原文出處:https://dev.to/taillogs/practical-ways-to-write-better-javascript-26d4 # 使用 TypeScript 改善 JS 的第一個技巧就是,不要寫 JS。寫 TypeScript 吧。它是微軟寫的一個語言,算是 JS 的母集合(一般的 JS 可以直接在 TS 裡面跑)。TS 在 JS 之上添加了一個全面的型別系統。長期下來,整個前端生態系,幾乎都支援 TS 語言了。下面介紹一下 TS 的優點。 **TypeScript 可以確保「型別安全」** 型別安全代表編譯器驗證了所有型別是否以「合法」的方式被使用。換句話說,如果你創建一個接受「數字」的函數 `foo`: ``` function foo(someNum: number): number { return someNum + 5; } ``` 該「foo」函數呼叫時要傳一個數字: 正確用法 ``` console.log(foo(2)); // prints "7" ``` 錯誤用法 ``` console.log(foo("two")); // invalid TS code ``` 除了需要花時間加型別以外,沒有其他缺點了。好處則是顯而易見。型別安全針對常見錯誤提供了額外預防,這對於像 JS 這樣鬆散的語言來說,是一件好事。 **TypeScript 的型別系統,讓你能重構大型應用程式** 重構大型 JS 應用程式是一場噩夢。主要是因為它不會檢查函數簽名。也就是說,JS函數隨便呼叫,編譯器都不會先報錯。舉個例,如果我有一個函數「myAPI」,由 1000 個不同的服務使用: ``` function myAPI(someNum, someString) { if (someNum > 0) { leakCredentials(); } else { console.log(someString); } } ``` 我稍微更改了呼叫簽名: ``` function myAPI(someString, someNum) { if (someNum > 0) { leakCredentials(); } else { console.log(someString); } } ``` 我必須自已 100% 去確認,使用此功能的1000 個地方,都有正確更新用法。漏掉的地方,在執行時就會壞掉。在 TS 中相同的情境如下: before ``` function myAPITS(someNum: number, someString: string) { ... } ``` after ``` function myAPITS(someString: string, someNum: number) { ... } ``` 如您所見,「myAPITS」函數跟在 JavaScript 中一樣修改。但是,這段程式碼無法順利產出 JavaScript,而是會出現無效 TypeScript 的錯誤提示,因為用到它的1000個地方,現在型別就出錯了。正是因為「型別安全」,這 1000 個案例會阻止編譯。 **TypeScript 使團隊溝通架構更容易** 正確設定 TS 後,要先定義介面跟類型,不然很難寫程式碼。這也順便提供了一種簡潔、可溝通的架構提案方法。例如,如果我想跟後端提出新的「請求」類型,可以使用 TS 將以下內容提交給團隊。 ``` interface BasicRequest { body: Buffer; headers: { [header: string]: string | string[] | undefined; }; secret: Shhh; } ``` 雖然也是要寫一點程式碼,但可以先提供以上內容作為初步想法、取得回饋,而不用一次設計完功能。像這樣強迫開發者先定義介面跟 API,能讓程式碼品質更好。 總體而言,TS 已經發展成為一種成熟且更可預測的 vanilla JS 替代品。當然還是要熟 JS,但我現在大多數新專案都是直接寫 TS。 # 使用現代功能 JavaScript是世界上最流行的程式設計語言之一。你可能會以為這語言已經被百萬開發者摸透了,其實不是。很多新功能是近期才加上去的。 **`async` 與 `await`** 長期以來,非同步、事件驅動的 callback 是 JS 開發中不可避免的: 傳統 callback ``` makeHttpRequest('google.com', function (err, result) { if (err) { console.log('Oh boy, an error'); } else { console.log(result); } }); ``` 上述程式碼會有越寫越多層的問題。JS 添加了一個新概念叫 Promises,可以避免嵌套問題。 Promises ``` makeHttpRequest('google.com').then(function (result) { console.log(result); }).catch(function (err) { console.log('Oh boy, an error'); }); ``` 與 callback 相比,Promise 的最大優勢是可讀性和可鏈性。 雖然 Promise 很棒,但它們仍然有一些不足之處。寫起來感覺有點怪。為了解決這個問題,ECMAScript 委員會添加一種使用 promise 的新方法,`async` 和 `await`: `async` 與 `await` ``` try { const result = await makeHttpRequest('google.com'); console.log(result); } catch (err) { console.log('Oh boy, an error'); } ``` 需要注意的是,`await` 的內容必須先被宣告為 `async`: 以前面 makeHttpRequest 舉例 ``` async function makeHttpRequest(url) { // ... } ``` 也可以直接 `await` 一個 Promise,因為 `async` 函數實際上只是 Promise 比較花哨的包裝寫法。這也意味著,`async/await` 代碼和 Promise 代碼在功能上是等價的。因此,請大方使用 `async/await` 吧。 **`let` and `const`** 以前大家寫 JS 都只能用 `var`。`var` 的變數作用域有一些獨特規則,一直讓人很困惑。從 ES6 開始,有了 `const` 跟 `let` 可以替代使用,幾乎不用再寫 `var` 了。 至於何時要用 const 何時要用 let 呢?永遠從 const 先開始使用。const 因為不可修改、更可預期,會讓程式碼品質更好。使用 let 的場景比較少,我寫 const 的頻率比 let 高 20 倍左右。 **箭頭 `=>` 函數** 箭頭函數是在JS中宣告匿名函數的簡潔方法。通常作為 callback 或 event hook 傳遞。 傳統的匿名 function ``` someMethod(1, function () { // has no name console.log('called'); }); ``` 在大多數情況下,這種風格沒有任何“不對”。但它的變數作用域很“有趣”,常導致許多意想不到的錯誤。有了箭頭函數之後,就沒這問題了。 匿名箭頭函數 ``` someMethod(1, () => { // has no name console.log('called'); }); ``` 除了更簡潔之外,箭頭函數還具有更實用的變數範圍界定。箭頭函數從定義它們的作用域繼承「this」。 在某些情況下,箭頭函數甚至可以更簡潔: ``` const added = [0, 1, 2, 3, 4].map((item) => item + 1); console.log(added) // prints "[1, 2, 3, 4, 5]" ``` 箭頭函數可以包括隱式的「return」語句。就不用寫大括弧、分號。 不過,這跟“var”被完全取代不同。傳統匿名函數仍然有需要的地方,例如類別方法定義。話雖如此,如果你總是預設使用箭頭函數,程式碼錯誤會少很多。 **展開運算子 `...`** 提取一個物件的鍵/值對,並將它們添加為另一個物件的子物件,是一種很常見的場景。從歷史上看,有幾種方法可以實現,但通通都很笨拙: ``` const obj1 = { dog: 'woof' }; const obj2 = { cat: 'meow' }; const merged = Object.assign({}, obj1, obj2); console.log(merged) // prints { dog: 'woof', cat: 'meow' } ``` 這寫法以前很常見,也很囉唆。多虧了「展開運算子」,再也不需要那樣寫了: ``` const obj1 = { dog: 'woof' }; const obj2 = { cat: 'meow' }; console.log({ ...obj1, ...obj2 }); // prints { dog: 'woof', cat: 'meow' } ``` 最棒的是,與陣列也可無縫接軌: ``` const arr1 = [1, 2]; const arr2 = [3, 4]; console.log([ ...arr1, ...arr2 ]); // prints [1, 2, 3, 4] ``` 它可能不是近期 JS 中最重要的功能,但它是我的最愛之一。 **範本文字(範本字串)** 字串處理太常見了,程式語言要能處理範本字串,才夠好用。處理動態內容、多行文字時,都會需要它: ``` const name = 'Ryland'; const helloString = `Hello ${name}`; ``` 我認為程式碼不言自明。看起來好多了。 **物件解構** 物件解構是一種從資料集合(物件、陣列等)中提取值,而無需反覆運算數據或顯式訪問其鍵的方法: 老方法 ``` function animalParty(dogSound, catSound) {} const myDict = { dog: 'woof', cat: 'meow', }; animalParty(myDict.dog, myDict.cat); ``` 新方法 ``` function animalParty(dogSound, catSound) {} const myDict = { dog: 'woof', cat: 'meow', }; const { dog, cat } = myDict; animalParty(dog, cat); ``` 不只這樣。您還可以在函數的簽名中定義解構: 解構範例二 ``` function animalParty({ dog, cat }) {} const myDict = { dog: 'woof', cat: 'meow', }; animalParty(myDict); ``` 它也適用於陣列: 解構範例三 ``` [a, b] = [10, 20]; console.log(a); // prints 10 ``` --- 以上,希望對您有幫助!

如何在 React 中漂亮地 render 一個列表:四點注意事項

面試的時候,常常會被問到這題。看似簡單,其實有一些進階注意事項,此篇與您分享。 - 原文出處:https://dev.to/andyrewlee/stand-out-in-a-react-interview-by-rendering-a-list-like-a-pro-1cn5 # 基本做法 以下是最基本做法。根據陣列內容,直接渲染成一個列表。 ``` import { useState, useEffect } from "react"; const App = () => { const [posts, setPosts] = useState([]); const [currentPost, setCurrentPost] = useState(undefined); useEffect(() => { const initialize = async () => { const res = await fetch("https://jsonplaceholder.typicode.com/posts"); const json = await res.json(); setPosts(json); }; initialize(); }, []); const onPostClick = (post) => { setCurrentPost(post); }; return ( <div> {currentPost && <h1>{currentPost.title}</h1>} <PostList posts={posts} onPostClick={onPostClick} /> </div> ); }; const PostList = ({ posts, onPostClick }) => { return ( <div> {posts.map((post) => ( <Post post={post} onPostClick={onPostClick} /> ))} </div> ); }; const Post = ({ post, onPostClick }) => { const onClick = () => { onPostClick(post); }; return <div onClick={onClick}>{post.title}</div>; }; export default App; ``` # 改進方法 以下是四個可以改進的方向,以及背後的原因。 ## 1. 指定 key 替每個元件提供一個 key 屬性,可以幫助後續 React 渲染時改善效能。要注意 key 屬性要是唯一值,不要直接用陣列索引當成 key。 ``` {posts.map((post) => ( <Post key={post.id} post={post} onPostClick={onPostClick} /> ))} ``` ## 2. 優化渲染 每次點擊列表項目時,都會重新渲染 `PostList` 和每個 `Post`。 ``` const Post = ({ post, onPostClick }) => { console.log("post rendered"); const onClick = () => { onPostClick(post); }; return <div onClick={onClick}>{post}</div>; }; ``` 可以使用 React 提供的 `memo` 功能來優化 `PostList` 元件。用 `memo` 包裝元件時,等於告訴 React:除非 props 改變,否則不要重新渲染這個元件。 ``` import { useState, useEffect, memo } from "react"; const PostList = memo(({ posts, onPostClick }) => { return ( <div> {posts.map((post) => ( <Post post={post} onPostClick={onPostClick} /> ))} </div> ); }); ``` 不過,實際跑下去,會發現還是重新渲染了。因為每次 currentPost 改變時,App 都會重新渲染。每次重新渲染都會重新建立 onPostClick 函數。當一個函數被重新建立時(即使函式內容一樣),都算是新的實體。所以技術上來說,props 確實發生了變化,所以 `PostList` 會重新渲染。 ``` const fn1 = () => {}; const fn2 = () => {}; fn1 === fn2; // => false ``` 這種狀況,就可以使用 useCallback hook 來告訴 React 不要重新建立函數。 ``` const onPostClick = useCallback((post) => { setCurrentPost(post); }, []); ``` 上面的例子中,使用 useCallback 沒問題,可以避免全部貼文被重新渲染。但要知道的是,並非什麼函式都適合包在 useCallback 裡面。 ``` const Post = ({ post, onPostClick }) => { const useCalllback(onClick = () => { onPostClick(post); }, []); return <div onClick={onClick}>{post.title}</div>; }; ``` 比方說,在 Post 元件使用 useCallback 就不太有意義。因為這個元件是輕量級的。應該只在有意義的情況下使用 useCallback(可以用 profiling 工具分析效能確認)。`useCallback` 有缺點:它增加了程式碼的複雜性。使用 useCallback 會在每次渲染時運行的額外程式碼。 ## 3. 元件卸載時清理乾淨 目前的元件沒有在卸載時進行清理。例如,如果在收到 URL 回應結果之前就離開頁面怎麼辦?這時應該要取消請求。 ``` useEffect(() => { const initialize = async () => { const res = await fetch("https://jsonplaceholder.typicode.com/posts"); const json = await res.json(); setPosts(json); }; initialize(); }, []); ``` `useEffect` 可以分為兩部分:掛載時運行的程式碼、卸載時運行的程式碼: ``` useEffect(() => { // When component mounts what code should I run? return () => { // When component unmounts what code should I run (clean up)? }; }, []); ``` 我們可以使用 AbortController ,並在清理時呼叫 controller.abort() 來取消請求。 ``` useEffect(() => { const controller = new AbortController(); const signal = controller.signal; const initialize = async () => { try { const res = await fetch("https://jsonplaceholder.typicode.com/posts", { signal }); const json = await res.json(); setPosts(json); } catch (err) { console.log(err); } }; initialize(); return () => { controller.abort(); }; }, []); ``` ## 4. 增加無障礙輔助功能 以上範例太過簡單,沒有太多無障礙功能可以加入。一旦應用程式變複雜,絕對應該要開始考慮這點。 有個簡單的無障礙測試:可以單獨只使用鍵盤就操作一個應用程式嗎? 關於這點,快速解法是:把每個項目都轉成按鈕,用鍵盤時就可以在元件之間切換。 ``` const Post = ({ post, onPostClick }) => { const onClick = () => { onPostClick(post); }; return <button onClick={onClick}>{post}</button>; }; ``` # 結論 在 React 中渲染列表,乍看之下,只是個簡單的面試問題。但其實可深可淺。下次面試時遇到這問題,可以思考一下此篇文章談到的各個面向。

20 個一行 JavaScript 就能完成的小任務

一行程式碼可以做到很多事。這邊有20個小任務都用一行就可以完成,給您參考! - 原文出處:https://dev.to/saviomartin/20-killer-javascript-one-liners-94f # 獲取瀏覽器 Cookie 的值 讀取 `document.cookie` 來查 cookie 的值 ``` const cookie = name => `; ${document.cookie}`.split(`; ${name}=`).pop().split(';').shift(); cookie('_ga'); // Result: "GA1.2.1929736587.1601974046" ``` # 將 RGB 轉換為十六進制 ``` const rgbToHex = (r, g, b) => "#" + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1); rgbToHex(0, 51, 255); // Result: #0033ff ``` # 複製到剪貼板 使用 `navigator.clipboard.writeText` 輕鬆將任何文字複製到剪貼板。 ``` const copyToClipboard = (text) => navigator.clipboard.writeText(text); copyToClipboard("Hello World"); ``` # 檢查日期是否有效 使用以下程式碼檢查給定日期是否有效。 ``` const isDateValid = (...val) => !Number.isNaN(new Date(...val).valueOf()); isDateValid("December 17, 1995 03:24:00"); // Result: true ``` # 查找一年中的第幾天 根據給定日期,找出是第幾天。 ``` const dayOfYear = (date) => Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24); dayOfYear(new Date()); // Result: 272 ``` # 將字串開頭大寫 Javascript 沒有內建的 capitalize 函數。我們可以使用以下程式碼來完成。 ``` const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1) capitalize("follow for more") // Result: Follow for more ``` # 求兩天之間的天數 使用以下程式碼查找 2 個給定日期之間的天數。 ``` const dayDif = (date1, date2) => Math.ceil(Math.abs(date1.getTime() - date2.getTime()) / 86400000) dayDif(new Date("2020-10-21"), new Date("2021-10-22")) // Result: 366 ``` # 清除所有 Cookie 透過 document.cookie 存取 cookie 並清除它,就可輕鬆清除網頁中的所有 cookie。 ``` const clearCookies = document.cookie.split(';').forEach(cookie => document.cookie = cookie.replace(/^ +/, '').replace(/=.*/, `=;expires=${new Date(0).toUTCString()};path=/`)); ``` # 生成隨機十六進制顏色碼 使用“Math.random”和“padEnd”屬性,生成隨機的十六進制顏色碼。 ``` const randomHex = () => `#${Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, "0")}`; console.log(randomHex()); // Result: #92b008 ``` # 從陣列中刪除重複項 使用 JavaScript 中的 `Set` 輕鬆刪除重複項。 ``` const removeDuplicates = (arr) => [...new Set(arr)]; console.log(removeDuplicates([1, 2, 3, 3, 4, 4, 5, 5, 6])); // Result: [ 1, 2, 3, 4, 5, 6 ] ``` # 從 URL 獲取查詢參數 您可以從 `window.location` 或原始 URL `goole.com?search=easy&page=3` 中輕鬆找出查詢參數 ``` const getParameters = (URL) => { URL = JSON.parse('{"' + decodeURI(URL.split("?")[1]).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') +'"}'); return JSON.stringify(URL); }; getParameters(window.location) // Result: { search : "easy", page : 3 } ``` # 把日期物件轉成時間 把日期物件以“hour::minutes::seconds”格式轉成時間。 ``` const timeFromDate = date => date.toTimeString().slice(0, 8); console.log(timeFromDate(new Date(2021, 0, 10, 17, 30, 0))); // Result: "17:30:00" ``` # 檢查數字是偶數還是奇數 ``` const isEven = num => num % 2 === 0; console.log(isEven(2)); // Result: True ``` # 求數的平均值 使用 `reduce` 方法計算多個數字之間的平均值。 ``` const average = (...args) => args.reduce((a, b) => a + b) / args.length; average(1, 2, 3, 4); // Result: 2.5 ``` # 滾動到頂部 您可以使用 `window.scrollTo(0, 0)` 方法自動滾動到頂部。將 `x` 和 `y` 都設為 0。 ``` const goToTop = () => window.scrollTo(0, 0); goToTop(); ``` # 反轉字串 您可以使用 `split`、`reverse` 和 `join` 方法輕鬆反轉字串。 ``` const reverse = str => str.split('').reverse().join(''); reverse('hello world'); // Result: 'dlrow olleh' ``` # 檢查陣列是否為空 ``` const isNotEmpty = arr => Array.isArray(arr) && arr.length > 0; isNotEmpty([1, 2, 3]); // Result: true ``` # 取得選中的文字 使用內建的 getSelection 屬性取得用戶選取中的文字。 ``` const getSelectedText = () => window.getSelection().toString(); getSelectedText(); ``` # 打亂陣列 使用 `sort` 和 `random` 方法打亂陣列。 ``` const shuffleArray = (arr) => arr.sort(() => 0.5 - Math.random()); console.log(shuffleArray([1, 2, 3, 4])); // Result: [ 1, 4, 3, 2 ] ``` # 檢測深色模式 使用以下程式碼,檢查用戶的設備是否處於深色模式。 ``` const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches console.log(isDarkMode) // Result: True or False ``` --- 希望這些程式碼,有給您一些靈感!

在 JavaScript 新版 ES2020 之中,值得留意的 10 個新功能

ES2020 已經上線一段時間了,但是滿多新功能都大家不太知道。這篇文章跟大家介紹一下! - 原文出處:https://dev.to/worldindev/10-new-javascript-features-in-es2020-that-you-should-know-3ohf # 1. BigInt BigInt 是最受期待的新功能之一,允許工程師處理資料時,能存一個更大的整數。 目前在 JavaScript 中可以儲存的最大整數是 `pow(2, 53) - 1`。BigInt 讓你可以存更大的數字。 ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/588khrk3rpei76gho4e9.png) 如上所示,需要在後面加上一個 `n`。這個 `n` 表示這是一個 BigInt ,讓 JavaScript 引擎(v8 引擎)能夠特別處理。 這個功能不向後兼容,因為傳統的數字系統是 IEEE754(不能支援這種大小的數字)。 # 2.Dynamic import 動態導入讓你可在程式碼中,有條件地動態導入模組。跟你現在用 Webpack 和 Babel 做的事一樣。 此功能讓你可以按需求讀取程式碼,也就是所謂的 code splitting。讓你不再需要 webpack 或其他模組打包工具就能做到。您還可以在 if-else 中有條件地載入程式碼。這有個額外好處,就是不會污染全域命名空間。 ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/utai4m6xcc1nk3aooqxf.png) # 3. Nullish Coalescing Nullish Coalescing 可以確實檢查 nullish 而不是 falsy 值。什麼是 nullish 與 falsy 值? 在 JavaScript 中,許多值都是 `falsy`,例如空字串、數字 0、`undefined`、`null`、`false`、`NaN` 等等。 但有時候你想要檢查 undefined 跟 null。這種情況下,就可以用新的運算子 `??` ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uupnryjugtdtb6xvv7yk.png) 如圖, **OR** 運算子始終回傳 truthy 值,而 ?? 運算子回傳 non-nullish 值。 # 4. Optional Chaining Optional Chaining 語法讓你可以取得深度嵌套的物件屬性,而不用擔心屬性不存在。如果找不到屬性,會回傳 undefined,而不會報錯壞掉。物件屬性可用,呼叫函數跟陣列也可以用。超方便!請參考: ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r4w5zkv64r0cs46xpjie.png) # 5. Promise.allSettled `Promise.allSettled` 方法接受一個 Promise 陣列,並且只有在所有 Promise 都完成時才 resolve 或 reject。 以前只能用 `race` 和 `all` 做出類似效果。 ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6xi1hpkcazxgxsl81d90.png) # 6. String#matchAll `matchAll` 是添加到 `String` 原型的新方法,與正則表達式相關。這將回傳一個迭代器,該迭代器依次返回所有匹配的組。舉例: ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nmmk478r36d1bfjovi1v.png) # 7. globalThis 如果你是寫跨平台的 JS 程式碼,可以在 Node 上運行、在瀏覽器運行、也可以在 web-workers 中運行,你很難操作全域物件。 因為對於瀏覽器來說它是 window ,對於 Node 來說是 global ,對於 web-workers 來說是 self。如果有其它的運行環境,它們的全局物件也都不同。 變成你需要自己寫一段來檢測環境。所以 ES2020 實作了 globalThis,無論您在哪裡執行,它始終引用全域物件: ![](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u5dczfi8moefwl4y1jo6.png) # 8. 模組命名空間匯出 在 JavaScript 模組中,可以使用以下語法: ``` import * as utils from './utils.mjs' ``` ES2020 新增了相對的匯出語法: ``` export * as utils from './utils.mjs' ``` 這等同於以下內容: ``` import * as utils from './utils.mjs' export { utils } ``` # 9. 定義好 for-in 順序 雖然大部份瀏覽器都實做了一樣的順序,但 ECMA 規範其實沒有指定 for (x in y) 的運行順序。在 ES2020 中正式標準化了。 # 10. import.meta `import.meta` 物件帶有一個 `null` 原型。 考慮以下模組,`module.js`: ``` <script type="module" src="module.js"></script> ``` 您可以使用 import.meta 物件取得有關模組的元信息: ``` console.log(import.meta); // { url: "file:///home/user/module.js" } ``` 對於 external scripts,它代表存取腳本的 URL,對於 inline scripts,它代表檔案的 URL。 --- 以上簡單分享,希望對你有幫助!

關於 JavaScript 開發的 8 個少見、但還不錯用小技巧

JavaScipt 是非常流行的程式語言,其中有些少見技巧,但還不錯用,這篇文章會分享八個,給您參考看看! - 原文出處:https://dev.to/worldindev/8-javascript-tips-tricks-that-no-one-teaches-24g1 # 函數繼承 函數繼承就是先寫一個基礎函數,再寫一個擴充函數,來擴充屬性與方法,會像這樣: ``` // Base function function Drinks(data) { var that = {}; // Create an empty object that.name = data.name; // Add it a "name" property return that; // Return the object }; // Fuction which inherits from the base function function Coffee(data) { // Create the Drinks object var that = Drinks(data); // Extend base object that.giveName = function() { return 'This is ' + that.name; }; return that; }; // Usage var firstCoffee = Coffee({ name: 'Cappuccino' }); console.log(firstCoffee.giveName()); // Output: "This is Cappuccino" ``` # .map() 的替代方案 `.map()` 有一個替代方案,就是 `.from()`: ``` let dogs = [ { name: ‘Rio’, age: 2 }, { name: ‘Mac’, age: 3 }, { name: ‘Bruno’, age: 5 }, { name: ‘Jucas’, age: 10 }, { name: ‘Furr’, age: 8 }, { name: ‘Blu’, age: 7 }, ] let dogsNames = Array.from(dogs, ({name}) => name); console.log(dogsNames); // returns [“Rio”, “Mac”, “Bruno”, “Jucas”, “Furr”, “Blu”] ``` # 數字轉字串/字串轉數字 通常,要讓數字轉為字串,會這樣寫 ``` let num = 4 let newNum = num.toString(); ``` 然後字串轉數字,會這樣寫 ``` let num = "4" let stringNumber = Number(num); ``` 但有個更快的寫法是: ``` let num = 15; let numString = num + ""; // number to string let stringNum = + numString; // string to number ``` # 使用長度來調整和清空陣列 在 javascript 中,我們可以改寫 length 內建方法,直接設定一個新值。 舉個例: ``` let array_values = [1, 2, 3, 4, 5, 6, 7, 8]; console.log(array_values.length); // 8 array_values.length = 5; console.log(array_values.length); // 5 console.log(array_values); // [1, 2, 3, 4, 5] ``` 還能用來清空陣列: ``` let array_values = [1, 2, 3, 4, 5, 6, 7,8]; console.log(array_values.length); // 8 array_values.length = 0; console.log(array_values.length); // 0 console.log(array_values); // [] ``` # 使用陣列解構來交換值 陣列解構讓陣列或物件的屬性,可以拆出來到變數中。還可以用它來交換兩個元素,舉例如下: ``` let a = 1, b = 2 [a, b] = [b, a] console.log(a) // result -> 2 console.log(b) // result -> 1 ``` # 刪除陣列中的重複元素 這個技巧很簡單。比方說,我創建了一個包含重複元素的陣列,然後我想刪除重複項: ``` const array = [1, 3, 2, 3, 2, 1, true, false, true, 'Kio', 2, 3]; const filteredArray = [...new Set(array)]; console.log(filteredArray) // [1, 3, 2, true, false, "Kio"] ``` # for 迴圈的簡寫版 可以這樣寫: ``` const names = ["Kio", "Rio", "Mac"]; // Long Version for (let i = 0; i < names.length; i++) { const name = names[i]; console.log(name); } // Short Version for (let name of names) console.log(name); ``` # 效能監測 下面這張圖是 google 用秒數提示效能: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i7ed89oyhcyyjhqirvc6.png 在 JavaScript 中也能做到,就像這樣: ``` const firstTime = performance.now(); something(); const secondTime = performance.now(); console.log(`The something function took ${secondTime - firstTime} milliseconds.`); ``` --- 以上八個技巧,希望對您有幫助!

JavaScript 中關於陣列的 13 個入門小技巧

陣列是 JavaScript 中最常用到的概念之一。處理資料時很常用到這種資料結構。這篇文章介紹一些陣列操作的基本方法,希望對你有幫助! - 原文出處:https://dev.to/duomly/13-useful-javascript-array-tips-and-tricks-you-should-know-2jfo # 1. 從陣列中移除重複項目 很經典的面試問題,需要從陣列中找出獨立值。使用 Set 資料型態,可以輕易完成這任務。這邊介紹兩種方法,一個使用 .from() 一個使用 ... 展開運算子。 ``` var fruits = [“banana”, “apple”, “orange”, “watermelon”, “apple”, “orange”, “grape”, “apple”]; // First method var uniqueFruits = Array.from(new Set(fruits)); console.log(uniqueFruits); // returns [“banana”, “apple”, “orange”, “watermelon”, “grape”] // Second method var uniqueFruits2 = […new Set(fruits)]; console.log(uniqueFruits2); // returns [“banana”, “apple”, “orange”, “watermelon”, “grape”] ``` 很簡單吧! # 2. 從陣列中抽換掉某個元素 這個情境也很常見。有一個簡單的好方法,就是使用 .splice ,參數分別是開始修改的位置、修改幾個元素、要更改成哪些值。 ``` var fruits = [“banana”, “apple”, “orange”, “watermelon”, “apple”, “orange”, “grape”, “apple”]; fruits.splice(0, 2, “potato”, “tomato”); console.log(fruits); // returns [“potato”, “tomato”, “orange”, “watermelon”, “apple”, “orange”, “grape”, “apple”] ``` # 3. 不用 .map() 的 map 功能 .map() 很常用、大家都會用,但有一個方法也很不錯,也很簡潔,就是 .from() ``` var friends = [ { name: ‘John’, age: 22 }, { name: ‘Peter’, age: 23 }, { name: ‘Mark’, age: 24 }, { name: ‘Maria’, age: 22 }, { name: ‘Monica’, age: 21 }, { name: ‘Martha’, age: 19 }, ] var friendsNames = Array.from(friends, ({name}) => name); console.log(friendsNames); // returns [“John”, “Peter”, “Mark”, “Maria”, “Monica”, “Martha”] ``` # 4. 清空陣列 有時候你會需要清空一個陣列。一個一個把元素刪掉太慢了,下面這個方法快多了:直接把長度設為 0 吧! ``` var fruits = [“banana”, “apple”, “orange”, “watermelon”, “apple”, “orange”, “grape”, “apple”]; fruits.length = 0; console.log(fruits); // returns [] ``` # 5. 把陣列轉換為物件 有時需要把陣列轉成物件。使用 ... 展開運算子可以很快完成這任務。 ``` var fruits = [“banana”, “apple”, “orange”, “watermelon”]; var fruitsObj = { …fruits }; console.log(fruitsObj); // returns {0: “banana”, 1: “apple”, 2: “orange”, 3: “watermelon”, 4: “apple”, 5: “orange”, 6: “grape”, 7: “apple”} ``` # 6. 陣列塞滿資料 有時需要把一個陣列塞滿某些資料。使用 .fill() 可以快速完成這任務: ``` var newArray = new Array(10).fill(“1”); console.log(newArray); // returns [“1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”] ``` # 7. 合併陣列 老方法是使用 .concat() 來合併。但有個新方法,就是用 ... 展開運算子,非常簡單俐落: ``` var fruits = [“apple”, “banana”, “orange”]; var meat = [“poultry”, “beef”, “fish”]; var vegetables = [“potato”, “tomato”, “cucumber”]; var food = […fruits, …meat, …vegetables]; console.log(food); // [“apple”, “banana”, “orange”, “poultry”, “beef”, “fish”, “potato”, “tomato”, “cucumber”] ``` # 8. 找出陣列交集 這也是 JavaScript 面試最常見的問題。這邊使用 filter 跟 .includes 來完成這任務。 ``` var numOne = [0, 2, 4, 6, 8, 8]; var numTwo = [1, 2, 3, 4, 5, 6]; var duplicatedValues = […new Set(numOne)].filter(item => numTwo.includes(item)); console.log(duplicatedValues); // returns [2, 4, 6] ``` # 9. 把 false 相關的值從陣列移除 false 相關值包含 false, 0, "", null, NaN, undefined。使用 .filter() 可以俐落地過濾陣列。 ``` var mixedArr = [0, “blue”, “”, NaN, 9, true, undefined, “white”, false]; var trueArr = mixedArr.filter(Boolean); console.log(trueArr); // returns [“blue”, 9, true, “white”] ``` # 10. 從陣列撈出隨機元素 有時需要隨機撈元素出來。根據陣列長度,隨機撈一個索引出來,就可以囉。 ``` var colors = [“blue”, “white”, “green”, “navy”, “pink”, “purple”, “orange”, “yellow”, “black”, “brown”]; var randomColor = colors[(Math.floor(Math.random() * (colors.length)))] ``` # 11. 逆轉陣列 不需要複雜的迴圈跟函數,也能逆轉一個陣列。這樣一行就可以: ``` var colors = [“blue”, “white”, “green”, “navy”, “pink”, “purple”, “orange”, “yellow”, “black”, “brown”]; var reversedColors = colors.reverse(); console.log(reversedColors); // returns [“brown”, “black”, “yellow”, “orange”, “purple”, “pink”, “navy”, “green”, “white”, “blue”] ``` # 12. .lastIndexOf() 方法 這個有趣的方法,可以找到特定元素最後一次出現的索引。如果陣列中有重複值,就可用上這方法。 ``` var nums = [1, 5, 2, 6, 3, 5, 2, 3, 6, 5, 2, 7]; var lastIndex = nums.lastIndexOf(5); console.log(lastIndex); // returns 9 ``` # 13. 陣列中全部數值加總 這也是面試常見考題。使用 .reduce 可以快速解決這問題。 ``` var nums = [1, 5, 2, 6]; var sum = nums.reduce((x, y) => x + y); console.log(sum); // returns 14 ``` # 結論 這 13 個小技巧,分別有一些進階觀念可以研究,這篇文章作為入門介紹,希望對您的工作有幫助!

開發 React 時,推薦使用這些 Best Practices

在開發 React App 時,遵循一些 best practices 會使您的程式碼品質提高,這篇文章列出一些給您參考。 - 原文出處:https://dev.to/iambilalriaz/react-best-practices-ege # 強烈推薦 VS Code 作為 IDE Visual Studio Code 有幾個超好用的 React 功能。強大的外掛生態系,對開發者大有幫助: - Prettier - ES Lint - JavaScript (ES6) code snippets - Reactjs code snippets - Auto import # 使用 ES6 語法 程式碼越漂亮越好。在 JavaScript 中,採用 ES6 語法可以讓程式碼更簡潔。 ## Arrow Functions ``` // ES5 function getSum(a, b) { return a + b; } // ES6 const getSum = (a, b) => a + b; ``` ## Template Literal ``` // ES5 var name = "Bilal"; console.log("My name is " + name); // ES6 const name = "Bilal"; console.log(`My name is ${name}`); ``` ## const $ let const $ let 有各自的變數作用域。const 宣告的變數不能修改,let 宣告的變數可以修改。 ``` // ES5 var fruits = ["apple", "banana"]; // ES6 let fruits = ["apple", "banana"]; fruits.push("mango"); const workingHours = 8; ``` ## Object Destructuring ``` var person = { name: "John", age: 40, }; // ES5 var name = person.name; var age = person.age; // ES6 const { name, age } = person; ``` ## Defining Objects ``` var name = "John"; var age = 40; var designations = "Full Stack Developer"; var workingHours = 8; // ES5 var person = { name: name, age: age, designation: designation, workingHours: workingHours, }; // ES6 const person = { name, age, designation, workingHours }; ``` ES6 的語法特性、彈性,很多值得您一試。 # JSX 使用 map 時記得加上 key array map 時,永遠記得替每個元素加上獨立的 key 值。 ``` const students = [{id: 1, name: 'Bilal'}, {id: 2, name: 'Haris'}]; // in return function of component <ul> {students.map(({id, name}) => ( <li key={id}>{name}</li> ))} </ul>; ``` # 元件名稱使用 PascalCase ``` const helloText = () => <div>Hello</div>; // wrong const HelloText = () => <div>Hello</div>; // correct ``` # 變數和函數名稱使用 camelCase ``` const working_hours = 10; // bad approach const workingHours = 10; // good approach const get_sum = (a, b) => a + b; // bad approach const getSum = (a, b) => a + b; // good approach ``` # ID 和 css class 名稱使用 kebab-case ``` <!--bad approach--> <div className="hello_word" id="hello_world">Hello World</div> <!--good approach --> <div className="hello-word" id="hello-world">Hello World</div> ``` # 永遠要檢查物件&陣列的 null & undefined 忘記檢查的話,常常會導致一堆錯誤。 所以要保持檢查的習慣。 ``` const person = { name: "Haris", city: "Lahore", }; console.log("Age", person.age); // error console.log("Age", person.age ? person.age : 20); // correct console.log("Age", person.age ?? 20); //correct const oddNumbers = undefined; console.log(oddNumbers.length); // error console.log(oddNumbers.length ? oddNumbers.length : "Array is undefined"); // correct console.log(oddNumbers.length ?? "Array is undefined"); // correct ``` # 避免 Inline Styling Inline styling 會讓 jsx 程式碼變得很亂。用單獨的 css 文件拆分出來比較好。 ``` const text = <div style={{ fontWeight: "bold" }}>Happy Learing!</div>; // bad approach const text = <div className="learning-text">Happy Learing!</div>; // good approach ``` 在 .css 文件中: ``` .learning-text { font-weight: bold; } ``` # 避免 DOM 操作 用 React state 為主,別用 DOM 操作 糟糕做法: ``` <div id="error-msg">Please enter a valid value</div> ``` ``` document.getElementById("error-msg").visibility = visible; ``` 推薦做法: ``` const [isValid, setIsValid] = useState(false); <div hidden={isValid}>Please enter a valid value</div>; ``` 使用 isValid 來管理 UI 顯示邏輯。 # 在 useEffect 記得清乾淨每個事件監聽器 加過的事件監聽器,都要記得清乾淨: ``` const printHello = () => console.log("HELLO"); useEffect(() => { document.addEventListener("click", printHello); return () => document.removeEventListener("click", printHello); }); ``` # 避免重複開發,多寫通用元件 讓程式碼越乾淨越好。相似的東西可以寫通用元件。再根據 props 內容傳遞來處理相異處即可: ``` const Input=(props)=>{ const [inputValue, setInputValue]=useState(''); return( <label>{props.thing}</label> <input type='text' value={inputValue} onChange={(e)=>setInputValue(e.target.value)} /> ) } ``` 在其他元件中,就能這樣用: ``` <div> <Input thing="First Name" /> <Input thing="Second Name" /> </div> ``` # 檔案要分類一下 相關檔案可以分類成一個資料夾。 例如在 React 寫一個導覽列,那就可以開一個資料夾,相關的 .js 與 .css 檔案放裡面。 # 寫 functional components 為主 簡單顯示一些東西、沒用到 state 的話,那寫 functional components 比寫 class components 好。 如果你會寫 react hooks 的話,那就連 state 都完全不成問題。 # 養成編寫輔助函數的習慣 有時你在 React App 中會需要一些通用功能。 這種情況,可以開一個 `helper-functions.js` 檔案,在裡面寫輔助函數,就可以到處使用了。 ## 使用三元運算子代替 if/else if 使用 `if/else if` 語句會使程式碼變得龐大。使用三元運算子,就簡潔、清楚多了: ``` // Bad approach if (name === "Ali") { return 1; } else if (name === "Bilal") { return 2; } else { return 3; } // Good approach name === "Ali" ? 1 : name === "Bilal" ? 2 : 3; ``` # 新增 index.js 檔案,讓匯入元件更簡單 如果你在 actions 資料夾中有一個 index.js 檔案,當你想在元件中導入時,會像這樣: ``` import { actionName } from "src/redux/actions"; ``` actions 後面的 index.js 可以省略不寫,就不用這樣囉唆了: ``` import { actionName } from "src/redux/actions/index"; ``` # Destructuring of Props 物件屬性名稱可以拆出來,後面用起來比較方便。 假設你的元件有 `name`、`age` 和 `designation` 這些 props: ``` // Bad approach const Details = (props) => { return ( <div> <p>{props.name}</p> <p>{props.age}</p> <p>{props.designation}</p> </div> ); }; // Good approach const Details = ({ name, age, designation }) => { return ( <div> <p>{name}</p> <p>{age}</p> <p>{designation}</p> </div> ); }; ``` # 不要嘗試在同一函數中,去碰修改過的 state 變數 在一個函數中,如果你正在為一個狀態變數賦值,在同一個函數中,是拿不到新值的 ``` const Message = () => { const [message, setMessage] = useState("Hello World"); const changeMessage = (messageText) => { setMessage("Happy Learning"); console.log(message); // It will print Hello World on console }; return <div>{message}</div>; }; ``` # 使用 === 運算子代替 == 在比較兩個值時,嚴格檢查變數型別比較好: ``` "2" == 2 ? true : false; // true "2" === 2 ? true : false; // false ``` --- 以上 Best Practices 供您參考,祝福您不斷變強!

10 個現代 JavaScript 中的好用語法:新手推薦

在 ES6 版本之後,Javascript 多了很多好用的語法,建議新手一定要學起來這幾招。 - 原文出處:https://dev.to/azure/modern-javascript-10-things-you-should-be-using-starting-today-1adm # -1- 展開運算子 Spred operator 在物件或陣列前面寫 ... 可以很輕鬆地把資料展開,舉例來說: ## Spread array ``` let firstHalf = [ 'one', 'two']; let secondHalf = ['three', 'four', ...firstHalf]; ``` 寫起來非常簡潔。不然原本要這樣寫: ## NO Array spread ``` let firstHalf = [ 'one', 'two']; let secondHalf = ['three', 'four']; for(var i=0, i <firstHalf.length; i++ ) { secondHalf.push(firstHalf[i]); } ``` 用在物件也可以,能夠合併屬性: ## Spread object ``` const hero = { name: 'Xena - Warrior Princess', realName: 'Lucy Lawless' } const heroWithSword = { ...hero, weapon: 'sword' } ``` 不然的話,就要用迴圈來跑全部屬性: ## NO Object spread ``` let keys = Object.keys(hero); let obj = {}; for(var i=0; i< keys.length; i++) { obj[keys[i]] = keys[props[i]]; } ``` 舊寫法其實有 Object.assign() 可以用,看起來會像: ``` const heroWithSword = Object.assign({}, hero, {weapon:"sword"}) ``` 但展開運算子還是簡潔多了: ``` const heroWithSword = { ...hero, weapon: 'sword' } ``` # -2- 其餘參數 Rest parameter 其餘參數能夠將剩下的參數蒐集到一個陣列中。JavaScript 有足夠彈性可以處理這些參數。通常會這樣寫: ``` function add(first, second, ...remaining) { return first + second; } ``` 以上只是加總前兩個參數,也就是 add(1,2) 或 add(1,2,3, 4) 結果一樣。接著這樣改寫: ``` function add(first, second, ...remaining) { return first + second + remaining.reduce((acc, curr) => acc + curr, 0); } ``` 這樣就會把全部參數都加總在一起了。 如您所見,前面加上 ... 就可以搜集其餘參數。這是一種命名變數的方式而已,比較少人知道這招,但可以知道一下。 # -3- 字串插值 String interpolation 看過這種寫法嗎? ``` class Product { constructor(name, description, price) { this.name = name; this.description = description; this.price = price; } getDescription() { return " Full description \n" + " name: " + this.name + " description: " + this.description } } ``` 看看那個 getDescription() 方法,又長、跨行、又難讀。在大多數程式語言都只能這樣寫。幸好,有些程式語言支援字串插值,包括 JavaScript,所以可以改寫如下: ``` getDescription() { return `Full description \n: name: ${this.name} description ${this.description} `; } ``` 反引號 ` 可以定義多行字串。再使用 ${} 進行插值。是不是好多了呢:) # -4- 屬性縮寫 Shorthand properties 雖然還沒搞懂,你可能早就在用了。在 ES5 需要這樣寫: ``` function createCoord(x, y) { return { x: x, y: y } } ``` 在 ES6 之後,如果 : 後面名稱一樣,可以直接省略,像這樣: ``` function createCoord(x, y) { return { x, y } } ``` 簡潔多了吧? # -5- 方法屬性 Method properties 在物件裡面指向方法的寫法。以下是 ES5 寫法: ``` const math = { add: function(a,b) { return a + b; }, sub: function(a,b) { return a - b; }, multiply: function(a,b) { return a * b; } } ``` 在 ES6 之後可以少寫一大堆,像這樣: ``` const math = { add(a,b) { return a + b; }, sub(a,b) { return a - b; }, multiply(a,b) { return a * b; } } ``` # -6- 解構 Destructuring 解構用得好,有益身心健康。 ## Object destructuring 這段: ``` function handle(req, res) { const name = req.body.name; const description = req.body.description; const url = req.url; log('url endpoint', url); // lots of logic happening dbService.createPerson( name, description ) } ``` 有點難讀吧,但要從多層深度挖資料,就會寫成這樣。還能怎麼辦?其實有以下妙招喔: ``` function handle(req, res) { const { body: { name, description }, url }, = req; log('url endpoint', url); // lots of logic happening dbService.createPerson( name, description ) ``` 變成俐落的一行了。 ## Array destructuring 不只物件能用,陣列也可以用,像這段: ``` const array = [1,2,3,4,5,6]; const a = array[0]; const c = array[2]; ``` 可以更優雅地改寫成這樣: ``` const array = [1,2,3,4,5,6]; const [a, ,c, ...remaining] = array; // remaining = [4,5,6] ``` 上面的模式配對,就可以拆出我們需要的變數。如果要跳過某值,就寫 , , 即可。我另外多寫了一個 rest parameter 來取得其餘資料。 ## Parameter matching 函數的參數也能這樣寫。當函數有超過 2-3 個參數時,業界慣例常常是這樣寫: ``` function doSomething(config) { if(config.a) { ... } if(config.b) { ... } if(config.c) { ... } } ``` 更漂亮的寫法其實是: ``` function doSomething({ a, b, c }) { if(a) { ... } if(b) { ... } if(c) { ... } } ``` # -7- 陣列方法 ES6 有大量好用的陣列方法,例如: - find(),回傳符合條件的項目,否則回傳 null - findIndex(),尋找項目的索引 - some(), 確認是否包含符合條件的項目 - includes(), 確認是否包含某個項目 舉例說明如下: ``` const array = [{ id: 1, checked: true }, { id: 2 }]; arr.find(item => item.id === 2) // { id: 2 } arr.findIndex(item => item.id === 2) // 1 arr.some(item => item.checked) // true const numberArray = [1,2,3,4]; numberArray.includes(2) // true ``` # -8- Promises + Async/Await 在只有 callback 能寫的年代,這種寫法很常見: ``` function doSomething(cb) { setTimeout(() => { cb('done') }, 3000) } doSomething((arg) => { console.log('done here', arg); }) ``` 用來寫非同步任務時,就會這樣寫。但現在我們有 promise 能寫了,所以可以這樣: ``` function doSomething() { return new Promise((resolve, reject) => { setTimeout(() => { resolve('done') }, 3000) }) } doSomething().then(arg => { console.log('done here', arg); }) ``` 多個流程還能整個串起來,就像這樣: ``` getUser() .then(getOrderByUser) .then(getOrderItemsByOrder) .then(orderItems => { // do something with order items }) ``` ## Async/await 接著還有 async/await 可以用。上方的範例,相關 promise 變成: ``` async function getItems() { try { const user = await getUser(); const order = await getOrderByUser(user); const items = await getOrderItemsByOrder(order); return items; } catch(err) { // handle error here, the suggestion to return something or rethrow } } getItems().then(items => { // do something with order items }) ``` 看起來像是同步,但其實非同步的一段程式碼:) # -9- 模塊 Modules 幾乎所有程式語言都支援模塊功能。將程式碼分為多個檔案,各自為獨立單元,就是模塊了。像這樣: ``` // math.js export function add(a,b) { return a + b; } export function sub(a,b) { return a - b; } export default (a,b) => a * b; // main.js import mult, { add, sub } from './math'; mult(2, 4) // 8 add(1,1) // 2 sub(1,2) // -1 ``` 使用 export 關鍵字來表示 add 跟 sub 是公開可用的。export default 代表不指定函數時直接導入的內容。在 main.js 中,將預設導入命名為 mult,然後指定導入函數 add 和 sub。 # -10- 箭頭函數 + this 整篇文章一直在用箭頭函數,其實只是另一種函數的寫法而已。以前要這樣寫: ``` function printArray(arr) { // do something } ``` 現在可以這樣寫: ``` const printArray = (arr) => { // do something } ``` ## 單行函數 函數還可以用一行寫完: ``` const add = (a,b) => a + b ``` 這種寫法可以省略 return 直接回傳結果。要回傳物件也可以,這樣即可: ``` const create = (a,b) = > ({ x: a, y: b }) ``` ## Lexical this 以前常常會搞混 this 代表什麼,舉例來說: ``` let array = [1,2,3]; function sum() { this.total = 0; arr.forEach(function(item) { this.total+= item; // `this` is the inner functions `this`, BAD }) return total; } ``` 這個例子中,this 在 forEach 指錯地方了。以前的解法是: ``` function sum() { this.total = 0; var self = this; arr.forEach(function(item) { self.total+= item; // now we are using `self`, it solves it but feels hacky }) return total; } ``` 雖然多寫個 self 變數可以解決,但實在很鳥。新的箭頭函數寫法則解決了這問題: ``` function sum() { this.total = 0; arr.forEach((item) => { this.total+= item; // all is well `this` points to outer function }) return total; } ``` # 結論 ES6 之後有很多好東西可以用,今天先介紹一些,希望對大家有幫助!

一行 JavaScript 就能完成的 7 個小任務

一行程式碼有時可以做到很多事。這邊有七個小任務都用一行就可以完成,給您參考! - 原文出處:https://dev.to/ruppysuppy/7-killer-one-liners-in-javascript-one # 洗亂陣列 在需要將陣列隨機打亂的時候,這行會很好用。 ``` const shuffleArray = (arr) => arr.sort(() => Math.random() - 0.5); // Testing const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; console.log(shuffleArray(arr)); ``` # 複製到剪貼板 在寫網站功能的時候,有時會需要這個功能。 ``` const copyToClipboard = (text) => navigator.clipboard?.writeText && navigator.clipboard.writeText(text); // Testing copyToClipboard("Hello World!"); ``` # 不重複元素 每種語言都有實作自己的 Hash List ,在 JavaScript 中,叫做 Set。可以使用 Set Data Structure 輕鬆地找出不重複元素。 ``` const getUnique = (arr) => [...new Set(arr)]; // Testing const arr = [1, 1, 2, 3, 3, 4, 4, 4, 5, 5]; console.log(getUnique(arr)); ``` # 檢測深色模式 深色模式日益流行,如果用戶在他們的設備中啟用了深色模式,最好將您的應用程序也切換到深色模式。 ``` const isDarkMode = () => window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches; // Testing console.log(isDarkMode()); ``` # 滑到頂部 新手常常發現滑動元素很難做。最簡單的方法是使用 scrollIntoView。加上 behavior 可以讓動畫更流暢。 ``` const scrollToTop = (element) => element.scrollIntoView({ behavior: "smooth", block: "start" }); ``` # 滑到底部 一樣使用 scrollIntoView 就可以,只需要將 block 值改成 end ``` const scrollToBottom = (element) => element.scrollIntoView({ behavior: "smooth", block: "end" }); ``` # 產生隨機顏色 如果您需要隨機色碼,可以參考這段: ``` const generateRandomHexColor = () => `#${Math.floor(Math.random() * 0xffffff).toString(16)}`; ``` --- 謝謝閱讀,希望對您有幫助!