Open Lichen5221 opened 3 years ago
ES6 = ES2015 在 2015 年正式發佈,新的版本有新的功能。
constant 常數,以此宣告後無法改變,如果以物件的話,可以改變儲存位置,改變了記憶體位置的值。只有物件和陣列的狀態下可以改。生存範圍也只有一個區塊。
作用域 Scope:變數的生存範圍
var:函式內的程式會不斷往上找,直到找到該變數。如果定義在函式裡面,該變數只會存在在該函式裡面,然後外面會無法找到函式裡面的定義變數。
let:生存範圍只有在一個區塊(if, while, for... )裡面,在區塊外的找不到區塊內的變數定義。
習慣不會變的就用 const 宣告,盡可能用 let 來宣告,作用域較小比較不會干擾到別人,debug 要抓的範圍也比較小。
字串不能換行,需要字串拼接才能多行。若相接字串太多容易少打、多打或搞混。
使用 ``,可變成多行字串。
console.log(`hello, ${name} now is ${new Date()}`) // ${變數},比字串更好懂,也可放 javascript 程式碼。
原來的 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
}
原來的 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))
好處:可以透過展開複製相同的東西,但記憶體位置不一樣,變成新的東西可更改。
如果裡面放了同一個陣列,那那個陣列的記憶體位置還是會一樣。
配合解構使用。
陣列上的使用:
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))
原先使用:
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)
簡化:
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 ,說要放文章但是課程影片上下都沒有連結所以先這樣。
和 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-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 的新功能
新語法非必要,不懂得怎麼用就不要用。
Node Package Manager
套件管理,有點像模組的系統。
除了這些以外,可以利用別人寫過的東西。
打 npm -v 可以檢查是否有安裝成功。
試用 left-pad:
與其全部上傳模組給別人,不如直接跟別人說有使用。
利用 .gitignore 忽視 node_module ,不會一起上傳,因為檔案太大。
如果出現 cannot find modules 的錯誤,代表沒有該模組,就可以利用 install 跟 package.json 檔案把模組裝回來。
安裝模組的時候一定要加 --save ,上傳的時候檔案才不會太大,別人又能知道要下載什麼。
上傳 GitHub 的時候一定要忽略 node_module 檔。
Jest
測試歸測試,檔案歸檔案。
將檔案的東西 exports 出去後,於測試檔案中引入。
test('解釋說明,可用中文。', () => { //ES6 的語法中,其實就是 function。 expect(sum(1, 2)).toBe(3); });
寫好後要用 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 )
先寫好函式的框架,然後先寫測試內容。