# Intermediate JavaScript ###### tags: `程式導師` `JavaScript` `課程筆記` ## Module 模組 使用已經撰寫好的特定功能程式碼,不需要重新打造輪子。 ```javascript // 到 node.js 查詢可用的模組,再引用到自己的檔案內 var os = require('os') ``` ### require/module.exports 與 import/export 將寫好的模組輸出 - `module.exports = <函式名稱>` - `exports.<自定義名稱> = <函式名稱>` 引入寫好的模組 - `var <自定義名稱> = require('<node 模組名稱>')` - `var <自定義名稱> = require('./<檔案名稱>')` ```javascript //將自己寫好的模組輸出,好讓其他檔案引用 //ES5 寫法 function double(n) { return n * 2 } module.exports = double // 建議使用這種寫法,可以不同資料型態處理 exports.double = double // 另種寫法,將 export 視為物件 //ES6 寫法 export function double(n) { return n * 2 } ``` ```javascript //引用他人寫好的模組 var myModule = require('./myModule') ``` ### npm/yarn 管理套件 node package manager = npm。 模組或套件的來源,除了自己寫、node.js 套件,還有 npm(類似套件倉庫)。 #### 使用 [npm](https://www.npmjs.com/) 1. 啟用 npm:在專案資料夾內,`npm init` 2. 安裝套件:`npm install <套件名稱>`,專案資料夾內會多一個 node_modules 資料夾,裡面會放套件程式碼。 3. 打包套件:`npm install <套件名稱> --save`,專案資料夾內會多一個 package.json,紀錄專案內使用到的套件。 4. 安裝所有專案內用到的套件:`npm install`。通常在下載他人專案後,要重新 build 才會用到。 :::info 在 npm5 之後,只要 `npm init` 後,以 `npm install` 安裝套件也會自動寫入 package.json 內。 ::: #### npm script npm script 指的是 package.json 檔案內的 scripts 的腳本。以 `npm run <腳本名稱>` 執行。 例如要執行名為 start 的腳本,就是 `npm run start`,依照下面 package.json 所寫的 start script,會在終端機輸入 `node index.js`,代表直接執行 index.js 檔案。 ```json { "name": "project", "version": "1.0.0", "description": "", "main": "index.js", //執行主程式 "dependencies": { "left-pad": "^1.3.0" }, "scripts": { "start": "node index.js", "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" } ``` ### 使用 [yarn](https://yarnpkg.com/getting-started/usage) 由 Facebook 開發的類似 npm 服務。使用方式也類似 npm,只是速度較快。 1. 安裝專案所有需要的套件:`yarn` 2. 安裝特定套件:`yarn add <套件名稱>`,也會自動更新 package.json 3. 執行 package.json 內的腳本:`yarn run <腳本名稱>` **比較 npm 與 yarn** | usage | npm | yarn | | ----- | --- | ---- | | start use the package manager | `npm init` | `yarn init` | | install package | `npm install` | `yarn add` | | development package | `npm install <套件名稱> --dev` | `yarn add <套件名稱> --dev` | ## Jest 測試 Jest 是現成的程式測試框架。使用前要先[安裝](https://jestjs.io/docs/en/getting-started.html)。 實務開發中,實際執行的程式碼檔案跟測試檔案是分開的。 1. 所以在測試程式碼前,要記得將程式碼 export,讓測試檔案能引用,這樣才能測試。 2. 新增測試檔:index.test.js(慣例命名都是以 .test.js 作為測試檔名的結尾) 3. 將測試檔內容改為要測試的內容 4. 新增 test 到 package.json 的腳本內:`"test": "jest"` 5. 在終端機執行 `npm run test` :::info 若覺得要更改腳本有點麻煩,想直接執行測試檔案的話,可以用 `npx jest index.test.js`。 npx 是在新版本的 npm 才有。 ::: ```javascript //需測試的程式碼:index.js function repeat(str, times) { var result = ''; for (var i=0; i<times; i++) { result += str } return result } module.exports = repeat //測試檔:index.test.js var repeat = require('./index.js') test('a 重複 5 次應該要等於 aaaaa',()=>{ expect(repeat("a", 5)).toBe("aaaaa"); }); ``` ### TDD 測試驅動開發 開發專案的順序是:先寫測試,再寫執行的程式碼。 TDD 開發的優點是能避免「懶得寫測試」的情況,因為必須先寫測試,再根據測試程式碼的結果修改程式碼,當程式碼完成後,測試本來就已完成了。 ## ES6 - var → let 與 const,var 的效用範圍是 function 內,cont 跟 let 則是在 block 內,因此會建議使用 let 與 const,避免互相干擾。 - template literals 樣板字串 - destructuring 解構 - spread operator - rest parameters - default parameters - arrow function ### Template Literals 樣板字串 ```javascript let userName = 'Yen'; userName ? console.log(`Hello ${userName}!`): //原本要用 console.log("Hello" + userName + " !") ``` ### Destructuring 解構 ```javascript //解構 array let arr = [1, 2, 3, 4] let [first, second, third, fourth] = arr console.log(first, second) //1 2 //解構 object let obj = { name: "Jack", gender: "male", address: "taipei", family : { father: "Mike" } } //原寫法 let name = obj.name console.log(name) // Jack let father = obj.family.father console.log(father) // Mike //解構寫法 let {name, gender, address, family:{father}} = obj console.log(name) // Jack console.log(father) // Mike ``` ### Spread Operator 展開運算子 ```javascript //展開 array let arr = [1, 2, 3] let arr2 = [4, 5, 6 ...arr] console.log(arr2) //[4, 5, 6, 1, 2, 3] //展開 object let obj = { a: 1, b: 2 } let obj2 = { ...obj, c: 3 } let obj3 = { ...obj, b: 3 } console.log(obj2) //{a:1, b:2, c:3} console.log(obj3) //{a:1, b:3},後面會蓋掉前面的值 ``` ### Rest Parameters 反向展開 - 將剩下的元素都集合在一起 - ...rest 只能放在最後一項,其後不能再有元素 ```javascript //反向展開 array let arr = [1, 2, 3] let arr2 = [1, ...rest] let [first, ...rest] = arr console.log(arr2) //[1, 2, 3] console.log(rest) //[2, 3] //反向展開 object let obj = { a: 1, b: 2, c: 3 } let {a, ...obj2} = obj console.log(obj2) //{b:2, c:3} //原寫法 function add (a, b) { return a + b } console.log(add(1, 2)) //反向展開 function function add(...args) { //args 是陣列,在這題就是 [1, 2] return args[0] + args[1] } console.log(add(1, 2)) ``` ### Default Parameters 預設值 為沒有輸入值的參數,自動設定一個預設值。 ```javascript function repeat(str, times=5) { //times 的預設值是 5 return str.repeat(times) } ``` ### Arrow Function ```javascript //舊版 var greeting = function() { console.log('Hello World!'); }; //新版:ES6 arrow function const greeting = () => console.log('Hello World'); ```