Basic ES6

Hannah Lin

ES6?

ES6 是 ECMAScript ( js 的規格標準) 第 6  版本的簡稱,又稱為 ES2015

Browser don't support?

Babel 是一種可以把 es6 轉成 es5 的編譯器

如果你已經是 Javascript 開發者,ES5 對你而言已經是一台好車,ES6將會為你的愛做最好的改裝。原本熟悉的 ES5 的方向盤和舒適座椅,氮氣加速 fat arrow function,安全氣囊 Let 和 Const ,符合 functional programming 資格的優質車面世。

Can I use

both

ES5 & ES6 ?

- Let/Const **
- Template String *
- Default Parameters *
- Object Property Shorthand *
- Arrow Function ***
- Rest Parameters & Spread Operator ***
- Destructuring ***

Summery

Let/Const

變數  / 常數,es5 並沒有常數變數的區分,用 var 就可以走天下

/* es5 Function scope -------------- */
function test(){
  var a = 10
}
 
if(true){
  var b = 20
}
 
console.log(a) // a is not defined 存取不到
console.log(b) // 存取得到
 
/* es6 Block scope -------------- */
function test() {
  let a = 10
}
 
if (true) {
  const b = 20
}
 
console.log(a) // a is not defined 存取不到
console.log(b) // b is not defined 存取不到
let/const

Function scope : var

只有新增 function 時才會有新 scope 出現

Block scope : let/const

只有在區塊內才讀取得到(不只 function, if 、for 都是區塊),區塊外是無法讀取的

Let 變數

當你會重新指定值,請用 let

Const 常數

一開始就要指定值,不可"再"指定值
Block scope
/* let -------------- */

for(let i=0; i<3; i++){
  console.log(i) 
}
// 0 1 2 i 的值不斷改變


//* const -------------- */

const b;
// 沒有指定值: Missing initializer in const declaration
 
const a = 10
a = 20 // TypeError: Assignment to constant variable. 錯誤
 
for(const i=0; i<3; i++){
  console.log(i) 
}
// 0 
// TypeError: Assignment to constant variable. 錯誤
Block scope

Const 常數

一旦使用 const 他就會占一個記憶體位址,
如果位址一樣但裡面值改變了,這樣狀況是 ok 的喔
// 這樣是被允許的
const a = []
a[0] = 1  // 在同一個位址指定值
 
const b = {}
b.foo = 123
const
//---- var
for(var  i = 0; i<3;i++){
  a()
}
// 5 
function a(){
  i =5;
  console.log(i)
}

No more var?

//---- let
for(let  i = 0; i<3;i++){
  a()  
}
// 5 5 5 
function a(){
  i =5;
  console.log(i)
}

Template Strings

不用再一堆 \ " ' + 了

/* es5 ------------ */ 
// demo 1
var template = 
'<table class="table()" onclick='show("hannah\'s")'>'+ a + '</table>'

// demo 2
var count = 35;
var tableHtml = [
'<table class="table">',
'<thead>',
'<tr> ',
'<td>Name</td'>',
'<td>Followers</td>',
'</tr> ',
'</thead> ',
'<tbody> ',
'<tr> ',
'<td>Hannah</td> ',
'<td>'+ count +'</td> ',
'</tr> ',
'</tbody> ',
'</table>'
].join("\n");
 
console.log( tableHtml )
/* es6 --------------------- */
// use `` and ${variable}
let count = 35;
let tableHtml = `
<table class="table">
    <thead>
        <tr>
            <td>Name</td <td>Followers</td </tr>
    </thead>
        <tbody>
            <tr>
                <td>Hannah</td>
                <td>${count}</td>
         </tr>
    </tbody>
</table>
`;
 
console.log( tableHtml)

Default Parameters

取代 es5 的 ||

/* es5 ----*/
/*
true  || true       // t || t returns true
false || true       // f || t returns true
true  || false      // t || f returns true
false || (3 == 4)   // f || f returns false
'Cat' || 'Dog'      // t || t returns "Cat"
*/
function(name, time){
     name = name || 'Hannah';
     time = time || 'Day';
     console.log(`Good $(name) , ${time} !`)
}
 


/* es6 ----*/
function(name = 'Hannah' , time = 'Day' ){
     console.log(`Good $(name) , ${time} !`)
}

Object Property Shorthand

/* es6 ------ */
function submit(name, comments, rating = 5){
     let data = {
         name, // same as name: name
         comments, // same as  comments: comments
         rating // same as rating: rating
     };
 
     for(let key in data){
          console.log(key +  ": " + data[key])
     }
}
submit("Hannah", "is cute")
// name: Hannah
// comments: is cute
// rating: 5

Arrow Function

跟傳統  function 比起來,除了語法簡短了許多,可讀性也大大提升

// es5
var func = function( x ){ return x+1 };
 

// es6
const func = x => x+1;
const funcA = x => x + 1     
// same as  const funcA = x => { return x + 1 }
 
const funcB = x => { x + 1 }
 
funcA(1) //2
funcB(1) //undefined
  • JS 語言中函式的設計,必須有回傳值
  • 沒有 {} 只適用於單行語句
  • => 前後要加空格
  • 是 function expression 的縮寫
  • => 前面不能換行,但後面可以直接換行(不建議)
  • 不能使用 arguments
  • arrow function 不能作為建構函式(constructor)使用
// !! 不建議這樣寫 !!
const funcA = x =>
x + 1
const funcB =
x =>
x + 1
// es5
var a  = function(){ console.log("Hi") };
var b  = function(x,y){ console.log("Hi") };


//es6
const a = () => {
    console.log("Hi")
}
const b = (x,y) => {
    console.log("Hi")
}
沒有參數或兩個以上參數記得加上空括號

Tradition function 

this 取決于執行這個 function 時的環境,會一直變動

Arrow function

this 是定義時的對象,而不是使用時的對象,會是固定的
this
// es5
const obj = { a: 1 }
function func() {
  // 這裡 this 會是 obj
  setTimeout( function() {
    // 這裡 this 會是 window
    // this.a必是undefined
    console.log(this.a)
  }, 2000)
}
func.call(obj)


// es6
const obj = { a:1 }
function func() {
  // this 會是 obj
  setTimeout( () => {
    // this 會是 obj 所以可以抓到 this.a
    console.log(this.a)
  }, 2000)
}
func.call(obj)
this

Not to use an Arrow Function

  1. 用物件字面文字定義物件時 {},物件中的方法
  2. 物件的 prototype 屬性中定義的方法
  3. DOM 事件處理的監聽者 (事件處理函式)
  4. 建構函式
// 用物件字面文字定義物件時,物件中的方法
const calculate = {
  array: [1, 2, 3],
  sum: () => {
    return this.array.reduce((result, item) => result + item)
  }
}
 
//錯誤: TypeError: Cannot read property 'array' of undefined
calculate.sum()

// 在物件的 prototype 屬性中定義的方法
function MyCat(name) {
  this.catName = name
}

MyCat.prototype.sayCatName = () => {
  return this.catName
}

cat = new MyCat('Mew')

cat.sayCatName() // undefined
Don't use Arrow Function
// DOM 事件處理的監聽者(事件處理函式)
const button = document.getElementById('myButton')

button.addEventListener('click', () => {
  this.innerHTML = 'Clicked button'
})

// 建構函式
const Message = (text) => {
  this.text = text
}

// 錯誤 Throws "TypeError: Message is not a constructor"

const helloMessage = new Message('Hello World!');
Don't use Arrow Function

Rest Parameters & Spread Operator

Rest Parameters

用在函式的參數,可以把他想成取代 arguments 的語法。把個別參數變成陣列

Spread Operator

...
用在陣列裡或呼叫 function,把陣列展開成個別值
// es5 
function sum() {
   var numbers = Array.prototype.slice.call(arguments),
       result = 0;
   numbers.forEach(function (number) {
       result += number;
   });
   return result;
}
console.log(sum(1)); // 1
console.log(sum(1, 2, 3, 4, 5)); // 15

// es6
function sum(…numbers) {
  var result = 0;
  numbers.forEach(function (number) {
    result += number;
  });
  return result;
}
console.log(sum(1)); // 1
console.log(sum(1, 2, 3, 4, 5)); // 15
Rest Parameters
// demo 1
var params = [ "a", 1, 7 ]
var other = [ 1, 2, ...params ] // [ 1, 2, "a", 1, 7 ]
 
var str = "hello"
var chars = [ ...str ] // [ "h", "e", "l", "l", "o" ]


// 拷貝陣列
const arr = [1,2,3]
const arr2 = [...arr]

arr2.push(4) //不會影響到 arr


// 也可用來呼叫 function
function sum(a, b, c) {
  return a + b + c
}
const args = [1, 2, 3]
sum(…args) // 6
Spread Operator

ARE YOU
TIRED?

Destructuring

在等號 (=) 的左邊是要被指定的變數,右邊的則是要指定的值

The destructuring assignment syntax is a JavaScript expression that makes it possible to extract data from arrays or objects using a syntax that mirrors the construction of array and object literals.

  • Array Destructuring 

  • Object Destructuring 

  • Neither array nor object destructuring

  • Destructuring with default

  • 配函式的傳入參數使用

常見使用狀況
//基本用法
const [a, b] = [1, 2] //a=1, b=2
 
//先宣告後指定值,要用let才行
let a, b
[a, b] = [1, 2]
 
// 略過某些值
const [a, , b] = [1, 2, 3] // a=1, b=3
 
// 其餘運算
const [a, ...b] = [1, 2, 3] //a=1, b=[2,3]
 
// 失敗保護
const [, , , a, b] = [1, 2, 3] // a=undefined, b=undefined
 
// 交換值
let a = 1, b = 2;
[b, a] = [a, b] //a=2, b=1
 
// 多維複雜陣列
const [a, [b, [c, d]]] = [1, [2, [[[3, 4], 5], 6]]]
 
// 字串
const str = "hello";
const [a, b, c, d, e] = str
Array Destructuring
// 基本用法
const { user: x } = { user: 5 } // x=5
 
// 失敗保護(Fail-safe)
const { user: x } = { user2: 5 } //x=undefined
 
// 賦予新的變數名稱
const { prop: x, prop2: y } = { prop: 5, prop2: 10 } 
// x=5, y=10
 
// 屬性賦值語法
const { prop: prop, prop2: prop2 } = { prop: 5, prop2: 10 } 
//prop = 5, prop2=10
 
// 相當於上一行的簡短語法(Short-hand syntax)
const { prop, prop2 } = { prop: 5, prop2: 10 } 
//prop = 5, prop2=10
 
// ES7+的物件屬性其餘運算符
const {a, b, ...rest} = {a:1, b:2, c:3, d:4} 
//a=1, b=2, rest={c:3, d:4}
Object Destructuring
// 錯誤的示範:
let a, b
{ a, b } = {a: 1, b: 2}


// 改進
let a, b
({ a, b } = {a: 1, b: 2}) //a=1, b=2
Object Destructuring

Practice

小小小練習

// es5 practice

var sum = function(num1, num2, num3) {
  var result = 0;
  var numbers = Array.prototype.slice.call(arguments);

  numbers.forEach(function (number) {
    result += number;
  });

  return result;
}

console.log(sum(1, 2, 3)); 
// es6 practice

const sum = (...numbers) => {
  let result = 0;
  numbers.forEach((number) => { result += number; })

  return result;
}

console.log(sum(1, 2, 3)); 

The End

Made with Slides.com