Module (模組/模塊)
為了方便維運,我們會將各個功能拆出來變成模組,再用主程式將各個模組串接上來。
一、借別人的東西用
//宣告變數將 module 引入,下方程式碼引入的是 node.js 的模組
// 用 require( ) 將寫好的功能引入進來,後面加字串表引入的套件名稱
let os = require('os')
console.log(os.platform())
二、把東西借給別人
(法一) module.exports
(1) 範例說明
// 檔案 myModule.js
function double(n) {
return n * 2
}
module.exports = double
/*
module.exports 後面接想輸出的東西
*/
// 檔案 code.js
var double = require('./myModule.js')
/* 寫檔案路徑 ./ ; 檔案類型 .js 可不加它會去找檔名
require 進來的東西會是我輸出的東西
*/
console.log(double(3))
(2) 輸出物件,它 require 進來的就會是物件
// 檔案 myModule.js
function double(n) {
return n * 2
}
var obj = {
double: double,
triple: function (n) {
return n * 3
}
}
module.exports = obj
// 檔案 code.js
var myModule = require('./myModule.js')
/* 寫檔案路徑 ./ ; 檔案類型 .js 可不加它會去找檔名
require 進來的東西會是我輸出的東西
*/
console.log(myModule.double(2), myModule.triple(10)) // 4 30
(法二) exports.x = x
(1) 範例說明
// 檔案 myModule.js
function double(n) {
return n * 2
}
var obj = {
double: double,
triple: function (n) {
return n * 3
}
}
exports.obj = obj
exports.triple = function(n) {
return n * 3
}
/*
exports 類似 {}
*/
// 檔案 code.js
var myModule = require('./myModule.js')
/* 寫檔案路徑 ./ ; 檔案類型 .js 可不加它會去找檔名
require 進來的東西會是我輸出的東西
*/
console.log(myModule.triple(4))
套件大倉庫:Node Package Manager (NPM)
NPM用途為管理套件,全世界人都可以使用。可以將寫好的套件(package) ,上傳至NPM與其他人分享。
- npm init ,可以在 dependencies 看到依賴關係
npm install 套件名稱
。 ls 會發現多了 node_modules/ 資料夾,npm 會將所有抓下來的東西放到 node_modules/- commit github, 將 node_moudle 排除(
.gitignore
),因為 node_moudle 這個資料夾太大了,裡面的東西都可以透過 npm install 指令安裝 - npm install 會檢視 package.json 將 dependencies 內容撈下來,若沒輸入npm install 會出現警示訊息
Cannot find module 'left-pad.js'
(一) 其他用途 : npm scripts
- 專案變大,各式檔案每個都很像入口點,法一、於 main 提示哪一個為主要檔案;法二、於 scripts 撰寫指令,於 cml 輸入,例如 :
npm run start
- 用途 : 開新專案前,將檔案清空、做一些事情 (移動檔案、上傳)......。
// 地點 = package.json
"scripts": {
"start":"node code.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
(二) yarn : dependency management
由臉書開發,用起來比較快的 npm
yarn
(= npm install),當我下載一個檔案,裡面沒有node_moudle ,可以透過這個指令去裝檔案yarn add 名稱
(= npm install 套件名稱),會自動更新 package and save
3.yarn run start
(= npm run start)
測試
(1) 初學者
- console.log() 加一些自己想的範例與 edge case
- 缺 : 不易規模化、不易執行
(一) unit test 單元測試
Jest 簡介 : fb 開發的測試框架
(二) TDD (Test-driven Development)
測試驅動開發,先把測試寫好,再寫 function
配備升級:ES6
(前言) ES5?ES6?這些到底是什麼
ECMAScript 是一套標準、規範,JS 就是透過上述標準來實作
。2015年官方正式發布第六版(ECMAScript6),ES6 = ES2015,(類似新的版本新的功能,就是ES6才會新增的東西)。ES用途 : 規格查詢、JS最新且正確詳細的資訊
(一) let / const / var
- const (常數constant) : 不能改變常數的值。TypeError: Assignment to constant variable.
物件跟陣列應的值為記憶體位置,所以仍可以透過 const 的方式修改裡面存放的內容
const b = {
number: 10
}
b.number = 20
// b 的值(記憶體位置)未改動,只是修改它指到記憶體位置裡面存放的東西
console.log(b)
let / var
1) Recall : scope (作用域),變數的生存範圍,先找到的先贏,找不到的再往上找。底下的東西才看到的上面的東西,上面的東西是看不到底下的東西(=外面東西看不到裡面)
2) var 的作用域為 function,let 與 const 的作用域為 block
3) 盡量用 let (因 : 作用域越小越不容易干預到其他人、較容易除蟲)
var a = 10
function test(){
var a = 100
console.log(a)
}
test() //100
function test(){
var a = 100
console.log(a)
}
test() //100
console.log(a) // a is not defined
(二) template literals
與字串有關的語法,以內嵌方式解決下列問題,並增加程式碼可讀性
Recall : 字串問題
1) 多行字串,需要使用字串拼接
var str = 'yiyo' +
'aaa' + '\n' +
'werwerwer'
console.log(str)
2) 字串拼接太多,單引號加號易搞混,出現語法問題
function sayHi(name) {
console.log('hello, ' + name + 'now is ' + new Date() )
}
sayHi('anna')
template literals
1) 多行字串,使用``
var str = `
apple
grape
orange
guava
`
console.log(str)
/* $ node code.js
apple
grape
orange
guava */
2) 字串拼接 : ${}
,{} 可以放 js 程式碼或變數
function sayHi(name) {
console.log(`hello, ${name.toUpperCase()} now is ${new Date()}` )
}
sayHi('anna')
//hello, ANNA now is Fri Apr 30 2021 20:05:17
(三) 解構 destructuring
優點 : 增加可讀性、可層層疊疊
陣列解構
var [fist, second, third, fourth] = [1, 2, 3, 4]
物件解構
``` js
const obj = {
player: 'bobby',
experience: 100,
wizardLevel: false
}
const player = obj.player
const experience = obj.experience
let wizardLevel = obj.wizardLevel
const { player, experience } = obj // = 這裡想像成 from
// 這和上面兩行做的事情是一樣的
let { wizardLevel } = obj
``` js
const obj = {
name: 'nick',
age: 30,
address: 'taiwan'
}
var {name, age, address} = obj
console.log(name)
function test({a, b}) {
console.log(a)
}
test ({
a: 1,
b: 2
})
// we can remove the declaration
// that we had with property and value if they're the same
const a = 'penny'
const b = true
const c = {}
const obj = {
a,
b,
c
}
console.log(obj) // { a: 'penny', b: true, c: {} }
(四) spread operator 把東西展開
把束縛給去掉,優點 : 進行複製,雖然值相等但因為存放的記憶體位置不同,所以不相等
- 陣列
function add(a, b, c) {
return a + b + c
}
var arr =[1, 2, 3]
console.log(add(...arr)) // 6
- 物件
var obj1 = {
a: 1,
b: 2,
}
var obj2 = {
z:1
}
var obj3 = {
...obj1,
c: 3
}
console.log(obj3)
(五) Rest Parameters 反向展開
會與解構一起使用
- 陣列
var arr = [1, 2, 3, 4, 5]
var [first, ...rest] = arr
console.log(rest) // [ 2, 3, 4, 5 ]
- 物件
var obj1 = {
a: 1,
b: 2,
}
var obj2 = {
...obj1,
c: 3
}
var {a, ...rest} = obj2
console.log(rest) //{ b: 2, c: 3 }
- 函式
// arg is an array, but argument is an object
function add(a, ...args) {
console.log(args)
return a + args[0]
}
console.log(add(1, 2))
(六) default parameter 加上預設值
可以透過等號後面加東西,當沒有東西、沒有東西傳進去時,它會是你設定的預設值。優點 : 用途廣,加上預設值就不用再判斷是否為空、undefined
- 物件
const obj = {
}
const { a = 123, b = 'hello'} = obj
console.log(a,b)
- 函式
function repeat(str = 'hello', times = 5) {
return str.repeat(times)
}
console.log(repeat()) // hellohellohellohellohello
(七) 箭頭函式
另一種宣告函式的語法,可以增加可讀性。將 function 省略掉,以箭頭的形式,若參數只有一個,可以將 () 也省略。相關學習 : this in JS
function test(n) {
return n
}
const test = (n) => {
return n
}
const test = n => {
return n
}
// if you have single return
const test = n => n
var arr = [1,2,3,4,5]
console.log(
arr
.filter(function(value){
return value > 1
})
.map(function(value) {
return value *2
})
) // [ 4, 6, 8, 10 ]
var arr = [1,2,3,4,5]
console.log(
arr
.filter(value => value > 1)
.map(value => value *2)
) // [ 4, 6, 8, 10 ]
const isValidAge = (age = 10) => age
(八) import & export
(九) Babel
ES6/7/8 透過 Babel 轉換成 ES5 ,新的語法透過 Babel 會轉換成更舊的語法,所以不需要擔心瀏覽器支援度的問題