Ashraf Latif

Back

2018-02-26

Pengenalan Ringkas Javascript ES6

Ini adalah pengenalan ringkas antara asas 'next-gen' javascript(js). Syntax next-gen ini kalau dapat dikuasai sangatlah membantu terutamanya bila kita guna framework / library js modern macam ReactJ, VueJS atau AngularJS.

let & const

Baca lanjut mengenai let : let
Baca lanjut mengenai let const : const

let & const asasnya untuk menggantikan cara kita declare variable dalam js. Gantikan let dengan var dan guna const kalau kita tak plan lansung untuk assign semula variable tersebut. Const = constant kan?

contoh:

// es5
var nama = "Ashraf Pandang Tak Jemu"
var pi = 3.14

// es6
let nama = "Ashraf Pandang Tak Jemu"
const pi = 3.14

ES6 Arrow Functions

Bacaan lanjut : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions

Arrow functions (anak panah => ) adalah cara lain untuk kita buat satu function dalam js. Syntax yang lebih pendek dan juga memberi beberapa kelebihan bila kita nak kekalkan skop this dalam js. (rujuk here).

Biasanya function di js ditulis begini:

function panggilSaya(nama) {
  console.log(nama)
}

atau begini kan?

const panggilSaya = function(nama) {
  console.log(nama)
}

Dengan Arrow functions ditulis begini::

const panggilSaya = nama => {
  console.log(nama)
}

**Penting: **

Jika function itu tak ada arguments, function declaration perlu disertakan kurungan parentheses '()'

const panggilSaya = () => {
  console.log("Sayang!")
}

Kalau ada hanya satu (1) argument, tak perlu disertakan kurungan:

const panggilSaya = nama => {
  console.log(nama)
}

Kalau kita nak return value saja, boleh guna shortcut:

const returnNama = nama => nama

Syntax atas ni samalah dengan yang bawah tapi shortcut

const returnNama = nama => {
  return nama
}

Exports & Imports

Dalam projek js moden, kod js selalunya diasingkan menjadi modul supaya setiap fail atau modul lebih mudah untuk sela dan setiap modul lebih fokus mengenai fungsi modul tersebut. Setiap file atau module mempunyai skop tersendiri. misalnya fail a.js dan file b.js. variable dari file a.js tidak akan boleh di akses secara terus di file b.js.

Untuk membolehkan content dari file a.js diakses oleh file b.js, file a.js perlulah di'export' untuk membolehkan contentnya diakses terlebih dahulan dan file b.js perlu import file a.js untuk menggunakannya.

terdapat 2 jenis exports.

  1. default (unnamed)
export default ...;
  1. named exports
export const dataRandom = ...;

Untuk import default exports

import namaPilihanAnda from "./path/to/file.js"

Ya, namaPilihanAnda adalah pilihan hati anda. pilih lah apa yg anda suka. haha.

Untuk import Named exports pula perlu diimport dengan namanya yg ditetapkan:

import { dataRandom } from "./path/to/file.js"

Satu file hanya boleh ada 1 default exports dan untuk named exports pula unlimited. Export la berapa banyak yang anda suka Ya boleh campur 1 default exports dan beberapa banyak pun named export pun yang anda suka. Dah bagi tahu ni.

Semasa import named exports anda boleh import semua named exports sekali gus seperti ini:

import * as ObjSukaHatiKau from "./path/to/file.js"

ObjSukaHatiKau ada lah js object. Ya nama dia suka hati kau nak letak apa. tanya lagi. choi. Nak akses object? ObjSukaHatiKau.dataRandom.

Classes

Classes adalah 1 ciri baru yg dibawa 'next-gen' JavaScript yang secara asasnya untuk menggantikan constructor function dan prototypes. Kita boleh define blueprint untuk objek JavaScript dengan class.

Contoh:

class Person {
  constructor() {
    this.name = "Max"
  }
}

const person = new Person()
console.log(person.name) // prints 'Max'

Contoh diatas bukan class, property class itu juga turut ditakrifkan (defined) iaitu 'name'. Untuk pengetahuan anda, this.name = name adalah syntax 'lama' untuk kita define properties. Di 'next-gen' JavaScript, Kita bole gunakan syntax 'baharu' yang lebih senang dan mudah (ya tanpa perlu mula dengan constructor) seperti dibawah:

class Person {
  name = "Max"
}

const person = new Person()
console.log(person.name) // prints 'Max'

Method juga boleh di'defined' begini dengan syntax baharu:

class Person {
  name = "Max"
  printMyName() {
    console.log(this.name) // 'this' perlu untuk merujuk class!
  }
}

const person = new Person()
person.printMyName()

atau macam ni pun boleh (arrow function):

class Person {
  name = "Max"
  printMyName = () => {
    console.log(this.name)
  }
}

const person = new Person()
person.printMyName()

Cara kedua memiliki kelebihan yang sama pada semua arrow function. Keyword this tidak menukar rujukannya / tidak 'bind' di mana-mana.

Penggunaan inheritance boleh dibuat dengan class:

class Human {
  species = "human"
}

class Person extends Human {
  name = "Max"
  printMyName = () => {
    console.log(this.name)
  }
}

const person = new Person()
person.printMyName()
console.log(person.species) // prints 'human'

Spread & Rest Operator

The spread and rest operators actually use the same syntax: ...

Yes, that is the operator - just three dots. It's usage determines whether you're using it as the spread or rest operator.

Using the Spread Operator:

The spread operator allows you to pull elements out of an array (=> split the array into a list of its elements) or pull the properties out of an object. Here are two examples:

const oldArray = [1, 2, 3]
const newArray = [...oldArray, 4, 5] // This now is [1, 2, 3, 4, 5];

Here's the spread operator used on an object:

const oldObject = {
  name: "Max",
}

const newObject = {
  ...oldObject,
  age: 28,
}

newObject would then be

    {
      name: 'Max',
      age: 28
    }

The spread operator is extremely useful for cloning arrays and objects. Since both are reference types (and not primitives), copying them safely (i.e. preventing future mutation of the copied original) can be tricky. With the spread operator you have an easy way of creating a (shallow!) clone of the object or array.

Destructuring

Destructuring allows you to easily access the values of arrays or objects and assign them to variables.

Here's an example for an array:

const array = [1, 2, 3]
const [a, b] = array

console.log(a) // prints 1
console.log(b) // prints 2
console.log(array) // prints [1, 2, 3]

And here for an object:

const myObj = {
  name: "Max",
  age: 28,
}

const { name } = myObj

console.log(name) // prints 'Max'
console.log(age) // prints undefined
console.log(myObj) // prints {name: 'Max', age: 28}

Destructuring is very useful when working with function arguments. Consider this example:

const printName = personObj => {
  console.log(personObj.name)
}

printName({ name: "Max", age: 28 }) // prints 'Max'

Here, we only want to print the name in the function but we pass a complete person object to the function. Of course this is no issue but it forces us to call personObj.name inside of our function. We can condense this code with destructuring:

const printName = ({ name }) => {
  console.log(name)
}

printName({ name: "Max", age: 28 }) // prints 'Max')

We get the same result as above but we save some code. By destructuring, we simply pull out the name property and store it in a variable/ argument named name which we then can use in the function body.