筆記、[JS102] 升級你的 JavaScript 技能:ES6 + npm + Jest


Posted by s103071049 on 2021-05-03

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與其他人分享。

  1. npm init ,可以在 dependencies 看到依賴關係
  2. npm install 套件名稱 。 ls 會發現多了 node_modules/ 資料夾,npm 會將所有抓下來的東西放到 node_modules/
  3. commit github, 將 node_moudle 排除(.gitignore),因為 node_moudle 這個資料夾太大了,裡面的東西都可以透過 npm install 指令安裝
  4. npm install 會檢視 package.json 將 dependencies 內容撈下來,若沒輸入npm install 會出現警示訊息 Cannot find module 'left-pad.js'

(一) 其他用途 : npm scripts

  1. 專案變大,各式檔案每個都很像入口點,法一、於 main 提示哪一個為主要檔案;法二、於 scripts 撰寫指令,於 cml 輸入,例如 : npm run start
  2. 用途 : 開新專案前,將檔案清空、做一些事情 (移動檔案、上傳)......。
// 地點 = package.json
 "scripts": {
    "start":"node code.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

(二) yarn : dependency management

由臉書開發,用起來比較快的 npm

  1. yarn(= npm install),當我下載一個檔案,裡面沒有node_moudle ,可以透過這個指令去裝檔案
  2. yarn add 名稱(= npm install 套件名稱),會自動更新 package and save
    3.yarn run start(= npm run start)

測試

(1) 初學者

  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

  1. 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 會轉換成更舊的語法,所以不需要擔心瀏覽器支援度的問題


#ES6 #npm #Jest







Related Posts

Inheritance

Inheritance

進階與經典題目

進階與經典題目

Git 與 Github 版本控制基本指令與操作入門教學

Git 與 Github 版本控制基本指令與操作入門教學


Comments