พื้นฐานการเขียน JavaScript ES2015 (ES6)

Feb 10, 2018 22:06 · 786 words · 4 minute read

ความเป็นมาของ JavaScript

เมื่อนานมาแล้ว JavaScript เป็นภาษา script ฝั่ง client ของ Netscape ซึ่งเป็น web browser ชื่อดังในสมัยนั้นครับ แล้วหลังจากนั้นไม่นาน Netscape ก็ได้นำเจ้า JavaScript นี้ไปฝากไว้กับ Ecma International ซึ่งเป็นองค์กรที่ก่อตั้งขึ้นเพื่อทำหน้าที่กำหนด standard ให้กับสิ่งต่างๆ โดยเฉพาะ เพื่อจะให้เข้ามาช่วยกำหนด standard ให้กับ JavaScript หลังจากนั้น JavaScript ก็ได้พัฒนาขึ้นมาเรื่อยๆ จนถึง JavaScript ES6

ในภาษา JavaScript ES6 จะมีการปรับเปลี่ยน Syntax การเขียนเพื่อให้เขียนได้ง่ายขึ้น ซึ่งเราจะมาเรียนรู้กันในบทความนี้ครับ

ไม่จําเป็นต้องมี Semicolon อีกต่อไป

ใน ES2015 ไม่จําเป็นต้องใส่ semicolon ตรงท้ายบรรทัดอีกต่อไป แต่ที่จริงแล้ว JavaScript ยังต้องใช้ semicolon อยู่ แต่ ES2015 นั้นจะเติม semicolon ให้เราอัตโนมัติ Code จะแลดูสวยขึ้นแบบนี้

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

การประกาศตัวแปรโดยใช้ let และ const

การประกาศตัวแปรแบบ let และ const จะต่างจากการประกาศตัวแปรแบบ var คือ การประกาศตัวแปรแบบ var นั้นเป็น function-scoped หรือพูดง่ายๆคือเราใช้ var ประกาศตัวแปรตรงจุดไหนก็ตาม แต่เมื่อ JavaScript เริ่มทำงาน การประกาศตัวแปรด้วย var นั้น ขอบเขตของตัวแปรจะอยู่ภายใต้ Function นั้นๆ

function foo(isValid) {
  if(isValid) {
    var x = 1
  }
  
  return x
}

จะเห็นว่า x ถูกประกาศใน if แต่สามารถเรียกจากภายนอก if ได้ แต่สำหรับ let และ const นั้นเป็น block-scoped หมายถึงประกาศตัวแปรอยู่ในบลอคไหนก็จะอยู่แค่ในบลอคนั้น

function foo(isValid) {
  if(isValid) {
    var x = 1
  }
  
  return x
}

x ข้างใน if และ นอก if จะเป็นคลละตัวกัน ความต่างของ let และ const คือ let นั้นหลังประกาศตัวแปรแล้ว สามารถเปลี่ยนค่าได้ แต่ const ใช้สำหรับประกาศค่าคงที่ ทำให้หลังประกาศแล้วไม่สามารถเปลี่ยนแปลงค่าได้ การใช้ const มีข้อควรระวังอยู่ดังนี้

const obj = { a: 1 }
obj.a = 2 // เราสามารเปลี่ยนค่าของ a ได้
console.log(obj) // { a: 2 }

จาก code ด้านบน obj จะเก็บ address ของ { a: 1 } เอาไว้ เราจะไม่สามารถเปลี่ยน address ได้ เช่น obj = {} แต่เราสามารถเปลี่ยนค่าภายใน Object ได้ ซึ่งจะไม่ทําให้ address เปลี่ยนไป

ES2015 Module

โดยปกติแล้ว JavaScript ไม่สามารถจัดการ Module ได้ด้วยตัวเอง จะต้องใช้ library CommonJS หรือ AMD แต่ใน ES2015 มาพร้อมกับการสนับสนุนการทำงานกับโมดูลได้ในตัว ซึ่งใช้ ES2015 เพื่อ import/export ของจากไฟล์หนึ่งไปอีกไฟล์หนึ่งได้แล้ว ดังนี้

// person.js
export const NAME = 'Thiti'
export function walk() {
  console.log('Walking...')
}

// main.js
// เลือกนำเข้าเฉพาะ NAME
import { NAME } from './person.js'

// main.js
// นำเข้าทุกอย่างที่ export จาก person
// แล้วตั้งชื่อใหม่ให้ว่า myPersion
import * as myPersion from './person.js'

หรือถ้า  module นั้นเรา Export แค่อย่างเดียวสามารถเขียนแบบนี้ได้

// circle.js
// สังเกตคำว่า default
export default class Circle {
  area() {
    
  }
}

// main.js
import Circle from './circle.js'

Destructuring

Destructuring เป็นการดึงข้อมูลบางส่วนออกมาจาก Object ตัวอย่างเช่น

let person = { 
  age: 24, 
  gender: 'male', 
  name: { 
    firstName: 'firstName', 
    lastName: 'lastName'
  } 
}

// ถ้าเราต้องการค่าเหล่านี้ออกจากอ็อบเจ็กต์ ต้องมาประกาศตัวแปรแบบนี้
let age = person.age 
let genger = person.gender
let name = person.name
let firstName = name.firstName
let lastName = name.lastName

// หากใช้ Destructuring จะเหลือแค่นี้
let { age, gender, name } = person
let { firstName, lastName } = name

// แต่ในความเป็นจริงแล้ว name เป็นเพียงแค่ทางผ่าน
// เราไม่ต้องการมัน เราต้องการแค่ firstName และ lastName
// จึงใช้ Destructuring ซ้อนเข้าไปอีกครั้ง
// เพียงเท่านี้ตัวแปร name ก็จะไม่เกิดขึ้นมาให้รำคาญใจ
let { age, gender, name: { firstName, lastName } } = person

Spread Operator

Spread Operator จะเป็นเครื่องหมายจุดสามจุด “…” ถ้าวางไว้หน้า Object หรือ Array ตัวไหนจะมีผลทำให้เครื่องหมายที่ครอบมันอยู่หลุดออก ตัวอย่าง

let obj1 = { a: 1, b: 2 }
let obj2 = { c: 3, d: 4 }
console.log({ ...obj1, ...obj2 }) // {"a":1,"b":2,"c":3,"d":4}

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

Arrow Function

เราสามารถประกาศ Function แบบ Arrow Function ได้ตามตัวอย่าง เทียบกับ การประกาศ Function แปบเก่า

// ES5
function(arguments) {

}

// ES2015
(arguments) => {

}

Arrow function ไม่ได้ต่างเพียงแค่ไวยากรณ์ที่เปลี่ยนไป แต่ arrow function นั้นยังเข้าถึง this จาก scope ที่ครอบมันอยู่ (Lexical binding) ดังนี้

function Dog() {
  this.color = 'white'
  
  setTimeout(() => { 
    // this ของ arrow function นี้จะหมายถึง
    // this ตัวบน
    console.log(this.color) 
  }, 100)
}

กรณีของ Arrow Function ถ้าตัว body ของฟังก์ชันไม่ครอบด้วย {} และมี statement เดียว จะถือว่าค่านั้นคือค่าที่ return ออกจากฟังก์ชัน

const fn = () => 3

console.log(fn()) // 3

เราสามารถไม่ต้องใส่ () ได้ถ้าพารามิเตอร์นั้นมีเพียงตัวเดียว

const arr = [1, 2, 3]
// มีค่าเท่ากับ arr.map((x) => x * x)
arr.map(x => x * x)

Default Values ของ พารามิเตอร์ที่ส่งเข้ามาในฟังก์ชัน

ใน ES5 เราตรวจสอบค่าของพารามิเตอร์ที่ส่งเข้ามาโดยเขียน code เพิ่มในฟังก์ชัน แต่สำหรับ ES2015 เราสามารถกำหนดค่าเริ่มต้นของพารามิเตอร์ได้เลยด้วยการประกาศไว้ในส่วนประกาศฟังก์ชัน ดังนี้

// ES5
function foo(genger) {
  gender = gender || 'male;
}

// ES2015
function foo(gender = 'male') {

}

Named Parameters

ถ้าเราส่ง Object เป็นพารามิเตอร์ และเราต้องการที่จะตรวจสอบค่าต่างๆภายในด้วย โดยถ้าค่าภายในส่งมาไม่ครบเราก็สามารถ set default ได้เหมือนกันดังนี้

function request({ method='GET', ssl=false }) {
  console.log(method)
}

request({})

Rest Parameters

ไม่ใช่พารามิเตอร์ทั้งหมดที่เราสนใจตั้งชื่อให้ ลองดูตัวอย่างต่อไปนี้ครับ เราจะทำการบวกเลขกันโดยผมต้องการรับพารามิเตอร์แค่สองค่า ค่าแรกเป็นค่าเริ่มต้นยัดใส่ตัวแปรชื่อ initial ส่วนที่เหลือจะมีกี่ตัวเลขไม่สน ยัดใส่ตัวแปรชื่อ rest ดังนี้

// ไม่ว่าจะส่งตัวเลขเข้ามากี่ตัว ตัวแรกจะเป็น initial 
// ส่วนตัวอื่นจะเก็บอยู่ในอาร์เรย์ชื่อ rest
function sum(initial, ...rest) {
  return rest.reduce((prev, cur) => prev + cur, initial)
}

console.log(sum(10, 1, 2, 3)) // 16

ลดความซ้ำซ้อนด้วยการเขียนให้สั้นลง

สามารถลดรูปการประกาศฟังก์ชันในอ็อบเจ็กต์ ดังนี้

// ES5
const obj = {
  foo: function() {
  
  }
}

// ES2015
const obj = {
  foo() {
  
  }
}

ถ้า key ของอ็อบเจ็กต์มีชื่อตรงกับตัวแปลที่จะใส่เข้าไปเป็น value แล้ว สามารถเขียนได้แบบนี้ครับ

// ES5
const foo = 'foo'
const bar = 'bar'

const obj = {
  foo: foo,
  bar: bar
}

// ES2015
const foo = 'foo'
const bar = 'bar'

const obj = {
  foo,
  bar
}

Template String

ปกติเราจะใช้ + ในการเชื่อมต่อ string แต่ใน ES2015 เราสามารถเขียนได้แบบนี้ครับ

const name = 'Thiti Yamsung'
console.log(`สวัสดี ผมชื่อ${name}`)

Class

สามารถสร้าง Class แบบใหม่โดยใช้คีย์เวิร์ด class ดังตัวอย่างนี้

// ประกาศคลาสผ่านคีย์เวิร์ด class
class Person {
  constructor(name, age) {
    this.name = name
    this.age = age
  }
  
  static species = 'Homo sapiens sapiens'
  
  walk() {
    console.log("I'm walking...")
  }
  
  print() {
    console.log(`My name is ${this.name}`)
    console.log(`I'm ${this.age}'`)
  }
}

const person = new Person('MyName', 99)
person.walk() // I'm walking...
person.print() // My name is MyName \n I'm 99'

// static method เรียกตรงผ่านคลาสได้เลย
console.log(Person.species)

// สำหรับการทำ inheritance สามารถใช้คีย์เวิร์ด extends ดังนี้
class Female extends Person {

}

ที่มาของข้อมูล www.babelcoder.com