Lichen5221 / Report-Daily

記錄每日上課內容與作業。
0 stars 0 forks source link

2021-05-05 #16

Open Lichen5221 opened 3 years ago

Lichen5221 commented 3 years ago

Node Package Manager

套件管理,有點像模組的系統。

除了這些以外,可以利用別人寫過的東西。

打 npm -v 可以檢查是否有安裝成功。

試用 left-pad:

npm i left-pad
var leftPad = require('left-pad') // 從內建找模組,內建沒有從系統找。
console.log(leftPad(123, 10, '0'))

與其全部上傳模組給別人,不如直接跟別人說有使用。

npm init //可全部 enter 略過,會多一個檔案 package.json 檔案。
npm install left-pad --save // 此時才能儲存你使用的模組給別人看,幫忙把模組的資訊寫進去 package.json檔案裡
npm rm -rf node_module/ //就算刪掉其他人也會因為有 package.json 而知道使用了什麼檔案
npm install //根據 package.json 下載模組

利用 .gitignore 忽視 node_module ,不會一起上傳,因為檔案太大。

如果出現 cannot find modules 的錯誤,代表沒有該模組,就可以利用 install 跟 package.json 檔案把模組裝回來。

安裝模組的時候一定要加 --save ,上傳的時候檔案才不會太大,別人又能知道要下載什麼。

上傳 GitHub 的時候一定要忽略 node_module 檔。

Jest

測試歸測試,檔案歸檔案。

function repeat(str, times) {
    var result = ''
    for (var i = 0; i < times; i++) {
        result += str
    }
    return result
}

module.exports = repeat

將檔案的東西 exports 出去後,於測試檔案中引入。

test('解釋說明,可用中文。', () => { //ES6 的語法中,其實就是 function。 expect(sum(1, 2)).toBe(3); });

var repeat = require('./module')
console.log(repeat('a', 6))
test('a 重複 6 次應該要等於 aaaaaa', function ( ) {
  expect (repeat('a', 5)).toBe('aaaaaa');
});

也可以這樣寫
var repeat = require('./index')
function test1() {
  repeat('a', 5)).toBe('aaaaaa;
}
test(a 重複 6 次應該要等於 aaaaaa', test1);

寫好後要用 jest 來跑而非 node 。

在 package.json 中 scripts 那裡有個 'test' ,可設定成跑 'jest' ,輸入 npm run test ,就會自動找所有 test.js 結尾的東西來檢查。

如果只想測試單一檔案,於 scripts 中 'jest' 後面寫檔名 'jest test.js'。

jest 並不像 node 直接內建在電腦裡,而是放在專案底下,所以直接命令 jest 執行行不通,但如果放在 package.json 就是在專案底下找。

如果 node 版本夠新,可以使用 npx 來執行,直接輸入 'npx jest 檔名' 即可。

老師說這樣測試起來比 console.log 更規模化,但他舉的這個例子我只覺得除了麻煩還有麻煩。

加入 describe('描述', function ( ) { 可放如重複 test 的東西 })

Unit Test 單元測試

上述所說的就是 Unit Test ,測試每一單元沒有出錯。

先寫測試再寫程式

Test-driven Development 測試驅動開發 ( TDD )

先寫好函式的框架,然後先寫測試內容。

Lichen5221 commented 3 years ago

配備升級:ES6

ECMAScript:標準、規範

ES6 = ES2015 在 2015 年正式發佈,新的版本有新的功能。

宣告變數的新選擇:let 與 const

constant 常數,以此宣告後無法改變,如果以物件的話,可以改變儲存位置,改變了記憶體位置的值。只有物件和陣列的狀態下可以改。生存範圍也只有一個區塊。

作用域 Scope:變數的生存範圍

var:函式內的程式會不斷往上找,直到找到該變數。如果定義在函式裡面,該變數只會存在在該函式裡面,然後外面會無法找到函式裡面的定義變數。

let:生存範圍只有在一個區塊(if, while, for... )裡面,在區塊外的找不到區塊內的變數定義。

習慣不會變的就用 const 宣告,盡可能用 let 來宣告,作用域較小比較不會干擾到別人,debug 要抓的範圍也比較小。

再也不需要字串拼接:Template Literals

字串不能換行,需要字串拼接才能多行。若相接字串太多容易少打、多打或搞混。

使用 ``,可變成多行字串。

console.log(`hello, ${name} now is ${new Date()}`) // ${變數},比字串更好懂,也可放 javascript 程式碼。

聽起來很酷的 Destructuring:解構

原來的 js 陣列:

const arr = [1, 2, 3, 4]

var first = arr[0]
var second = arr[1]
var third = arr[2]
var forth = arr[3]

console.log(second, third)

陣列解構:

const arr = [1, 2, 3, 4]

var [first, second, third, forth] = arr // = [1, 2, 3, 4]

console.log(second, third)

原來 js 物件:

const obj = {
  name: 'nick',
  age: 30,
  address: 'Taiwan'
}

var name = obj.name
...

console.log(name, age, address)

物件解構:

const obj = {
  name: 'nick',
  age: 30,
  address: 'Taiwan'
  family: {
    father: 'Nick'
}

var {name, age, address} = obj //變數名稱要跟物件內容一致才能對應
var {family} = obj
var {father} = family // 兩者在解構中如何使用:var {family: {father}} = obj 

console.log(father) //只有最後一層會拿出來,此時輸入 family 不會顯示。

有時候一層就夠了,雙層只是要讓大家知道可以這樣使用。

原來 js 函式使用:

function test(obj) {
  console.log(obj.a)
}

test( {
  a: 1,
  b: 2
}

函式解構:

function test({a, b}) {
  console.log(a)
}

test( {
  a: 1,
  b: 2
}
Lichen5221 commented 3 years ago

把東西展開:Spread Operator

原來的 js 陣列:

var arr = [1, 2, 3]
var arr2 = [4, 5, 6, arr]

console.log(arr2) // [4, 5, 6, [1, 2, 3]]

使用展開的 js 陣列:

var arr = [1, 2, 3]
var arr2 = [4, 5, 6, ...arr] // ...為展開的使用方式,可隨意放置。

console.log(arr2) // [4, 5, 6, 1, 2, 3]
function add(a, b, c) {
  return a + b + c
}

console.log(add(1, 2, 3))
function add(a, b, c) {
  return a + b + c
}

var arr = [1, 2, 3]
console.log(add(...arr)) //展開 arr

使用展開的物件:

var obj1 = {
  a: 1,
  b: 2
}

var obj2 = {
  z: 1
}

var obj3 = {
  ...obj1,
  b: 3 //印出來 b 會變成 3 ,後面優先,如果 obj1 在後面則會覆蓋前面相同的數值。
  c: 3
}
console.log(obj(3))

好處:可以透過展開複製相同的東西,但記憶體位置不一樣,變成新的東西可更改。

如果裡面放了同一個陣列,那那個陣列的記憶體位置還是會一樣。

反向的展開:Rest Parameters

配合解構使用。

陣列上的使用:

var arr = [1, 2, 3, 4]
var [first, ...rest] = arr
console.log(rest) //會出現 [2, 3, 4]

rest 只能放在最後面。

物件上的使用:

var obj = {
  a: 1,
  b: 2,
  c: 3
}

var {a, ...obj2} = obj // rest 也能改成其他名字

console.log(a, obj2)

組合展開與反展開:

var obj = {
  a: 1,
  b: 2
}

var obj2 = {
  ...obj,
  c: 3
}

var {a, ...rest} = obj2

console.log(rest)

function 上使用:

function add(...args) { //把數入的值變成陣列 [1, 2]
  return args[0] + args[1]
}
console.log(add(1, 2))
function add(a, ...args) { // ...args 變成 [2]
  return a + args[0]
}
console.log(add(1, 2))

加上預設值:Default Parameters

原先使用:

function repeat(str, times) {
  return str.repeat(times)
}
console.log(repeat('abc', 5))

使用預設值:

function repeat(str, times = 5) { //當原來的參數中沒有給數字時
  return str.repeat(times)
}
console.log(repeat('abc'))
const obj = {
  b: 2
}

const {a = 123, b} = obj //沒有東西的時候會變成預設值

console.log(a, b)
Lichen5221 commented 3 years ago

Function 的更新:箭頭函式 Arrow Function

簡化:

function test(n) { //原來的 function
  return n
}

const test = function(n) { 
  return n
}

const test = (n) => { //箭頭函式
  return n
}

原來:

var arr = [1, 2, 3, 4, 5]
console.log(
  arr.
    fliter(function(value) {
    return value > 1
    })
    .map(function(value) {
      return value * 2
    })
)

使用箭頭函式:

var arr = [1, 2, 3, 4, 5]
console.log(
  arr.
    fliter(value => {
    return value > 1
    })
    .map(value => {
      return value * 2
    })
)

更簡化:

var arr = [1, 2, 3, 4, 5]
console.log(
  arr.
    fliter(value => value > 1)
    .map(value => value * 2)
)

可讀性更高。

關於 this ,說要放文章但是課程影片上下都沒有連結所以先這樣。

Import 與 Export

和 module 的 exports 跟 require 類似。

export function add(a, b) {
  return a + b
}

export const PI = 3.14

也可以這樣寫:

function add(a, b) {
  return a + b
}

const PI = 3.14

export { //並非 obj,無法像 obj 一樣使用
  add, // add as addFunction,則在 import 的時候要寫 addFunction 它才會認得這個東西。
  PI
}

import 的部分:

import {add, PI} from './ export 所在的檔案名稱' // import {addFunction as a} 可將原函式名稱縮短,底下印出參數的部分就要使用更改後的名稱才會讀取。
console.log(add(3, 5), PI)

node js 還認不得 import,所以要輸入 nix babel-node 檔名,來執行 import 。

如果想要輸入所有 export 的東西:

import * as 參數名稱 from './ 檔案名稱' //把東西全部 import 進來取個名
console.log(參數名稱.addFunction(3, 5), 參數名稱.PI) //參數名稱隨便取

額外使用法:

export default function add(a, b) {
  return a + b
}

export const PI =3 .14

import 端即可:

import add, {PI} from './檔案名稱'
console.log(add(3, 5), PI)

import {default as add, PI} from './檔案名稱' // default 是關鍵字所以要額外給名字
console.log(add(3, 5), PI)

Babel

如果想用的東西支援度不夠,就開發一個東西讓新語法轉成舊語法。多數前端的工具都是為了支援舊的瀏覽器而開發。

Babel 可把新語法轉成舊語法。

Babel-node 當成 node 執行就可以了。這不能用在產品上,效能不好。

如果要用在產品上,會先 compile 好,再用 node 去執行 compile 好的檔案。

設定步驟: 安裝必要套件:npm install --save-dev @babel/core @babel/node @babel/preset-env 新增 .babelrc 並打開 填入下列內容,告訴 babel 要用這個 preset: { "presets": ["@babel/preset-env"] } 最後使用 npx babel-node index.js 即可

其他

ES6 剩下請參考 ES6 的新功能

新語法非必要,不懂得怎麼用就不要用。