[ JavaScript 12 ] ES6 新增特性


Posted by tzutzu858 on 2020-06-29

ECMAScript : 標準、規範
JavaScript 根據這個標準來實作
圖片取自維基百科


const 、 var 和 let

ES6 之後多了兩個宣告變數的方法 letconst
不錯的文章說明:JavaScript: var, let, const 差異
Babel : JavaScript 編譯器、轉譯器,其中一個功能可將 ES6 轉碼為 ES5

const 就是 constant 常數

const b = '123'
b='456'
console.log(b)

會出錯: Assignment to constant variable.
不能改變常數的值

const b 
b = 123

會出錯: Missing initializer in const declaration
const 缺少初始值

所以宣告 const ,一定要一開始就給它值,並且不能改變

但以下改變值是可以的嗎?

const b = {
   number :123
}   
b.number = 456
console.log(b)

印出 { number: 456 }
程式也沒問題,因為記憶體位置並沒有改變
但如果用下面寫法便會出錯顯示 : Assignment to constant variable.

const b = {
    number :123
}   
b = {
    number :456
}
console.log(b)

原因是因為,一開始 b 假設存一個記憶體位置叫 0x10
如果是 b.number = 456 那它是去 0x10 改變裡面的值
但如果是 b = { number :456 } 那就是重新給他一個新的記憶體位置,那這樣就不是 const
除了 obj , array, date, function 都有相同特性

const arr = []
arr.push(123)
// 這樣 OK
const arr = [1, 2, 3]
arr[0] = 4
// 這樣 OK,因為也沒有改變到記憶體位置
const arr = []
arr = [4]
// 這樣就不行

var 和 let

作用域 (Scope)
變數的生存範圍
let 和 const 用來宣告區塊裡的變數,只活在 { } 裡面

function test() {
   var a = 10  
   console.log(a)  // 印出 10
}   

test()
console.log(a) // 這個找不到
function test() {
   if (10 > 5) {
      var a = 10
   }   
   console.log(a)  // 印出 10
}   

test()
// 在 function 程式碼裡面,都可以看到 a 這個變數
function test() {
   if (10 > 5) {
      let a = 10
   }   
   console.log(a)  // Error : a is not defined 
}   

test()
// 若是宣告 let , 那他只會在 block 生存範圍
// const 也是一樣,只會在 block 生存範圍

Template Literals

解決多行字串

var str = `
hi
how 
are
you
`
console.log(str)


/*
印出
hi
how 
are
you
*/
function sayHi(name) {
   console.log(`hello , ${name} now is ${new Date()}`)
}

sayHi('nick') 

//印出 hello , nick now is Mon Jun 29 2020 17:48:10 GMT+0800 (台北標準時間)

Destructuring:解構

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

var [first, second, third, fourth] = arr

console.log(second, third)
const obj = {
   name: 'nick',
   age: 30,
   address: 'taiwan',
   family:{
      father: 'hello'
   }   
}   

var {name, age, address} = obj
var {family:{father}}=obj
console.log(address)
console.log(father)

把東西展開: Spread Operator

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

console.log(arr2) // 印出[4,1,2,3,5,6]
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,
   c:3
}

console.log(obj3)  // 印出 { a: 1, b: 2, c: 3 }
var obj1 = {
  a:1,
  b:2
}

var obj2 = {
   z:1
}

var obj3 = {
   ...obj1,
   b:3
}

console.log(obj3)  // 印出 { a: 1, b: 3 }

// 後面會優先
var obj1 = {
  a:1,
  b:2
}

var obj2 = {
   z:1
}

var obj3 = {
   b:3,
   ...obj1 
}

console.log(obj3)  // 印出 { b: 2 , a: 1 }

// 後面會優先
var nestedArray = [4]
var arr = [1, 2, 3, nestedArray]
console.log('arr:', arr)
var arr2 = [...arr]
console.log('arr2:', arr2)
console.log('arr === arr2 是',arr === arr2)
console.log('arr[3] === arr2[3] 是',arr[3] === arr2[3])

印出 :
arr: [ 1, 2, 3, [ 4 ] ]
arr2: [ 1, 2, 3, [ 4 ] ]
arr === arr2 是 false
arr[3] === arr2[3] 是 true

arr[3] === arr[3] 是 true 的原因是把 arr 複製到 arr2 ,arr[3] 是個 arrary , 所以會指向同一個記憶體


「反向」的展開:Rest Parameters

var arr = [1, 2, 3, 4]
var [first,...rest] = arr

console.log(rest) // 印出[2, 3, 4]
var obj = {
  a:1,
  b:2,
  c:3
}

var {a, ...obj2} = obj

console.log(obj2) // 印出 { b:2, c:3}
function add(a, ...args) {
   console.log(args)  //印出[2]
   return a + args[0]
 }

 console.log(add(1, 2))  //印出 3

加上預設值:Default Parameters

給預設值的概念
原本寫法

function repeatFun(str, times){
  return str.repeat(times) 
}

console.log(repeatFun('abc'))  //會出錯,因為沒有輸入 times 的引數
console.log(repeatFun('abc', 5)) // 印出 abcabcabcabcabc
function repeatFun(str = 'hello', times = 5){
  return str.repeat(times) // 印出 5
}

console.log(repeatFun('abc'))  // 印出 abcabcabcabcabc

console.log(repeatFun()) // 印出 hellohellohellohellohello

Function 的更新:箭頭函式 Arrow Function

function test(n) {
   return n
}  

const test = (n) => {
   return n
}

原本的

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

把 function 去掉,加一個箭頭,只有一個參數,()也可以省略掉

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

再省略

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

Import 與 Export

Export

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

export const PI = 3.14

Import

import {add, PI} from './utils'

console.log(add(3, 5))

不能直接用 node 跑,沒有 node.js 版本還沒有原生支援
所以要下 npx babel-node index.js 這個 npx babel-node 指令來跑

Export 有幾種方式:
export function add(){},使用 import {add} 引入
export { add },與上面那種一樣
export default function add(),使用 import add 引入,不需要加大括號
如果想要用其他名字,可以用 as 取別名,例如說 export { add as addFunction }

可以用 import * as utils from 'utils' 把全部都 import 進來


Babel 簡介與基本使用方法

Babel 的安裝說明:https://babeljs.io/docs/en/next/babel-node.html

設定步驟:

安裝必要套件:npm install --save-dev @babel/core @babel/node @babel/preset-env
新增 .babelrc
填入內容,告訴 babel 要用這個 preset:

{
 "presets": ["@babel/preset-env"]
}

最後使用 npx babel-node index.js 即可


更多 ES6 新增的語法:https://github.com/DrkSephy/es6-cheatsheet


#javascript







Related Posts

GDB Cheatsheet

GDB Cheatsheet

[Day 04] - Vault dynamic secrets engine - AWS

[Day 04] - Vault dynamic secrets engine - AWS

在 oh-my-zsh 中自訂常用的 alias (重啟 terminal 後仍然有效)

在 oh-my-zsh 中自訂常用的 alias (重啟 terminal 後仍然有效)


Comments