ES6 - The Good Part (Phần 2)
Bài đăng này đã không được cập nhật trong 7 năm
Tiếp nối phần 1 https://viblo.asia/luongs3/posts/L4x5xQ1mKBM Phần 2 tôi sẽ trình bày về các nội dung còn lại là:
- destructuring
- spread operator
- for of vs for in
- Array methods
- class
Destructuring
Destructure có ý nghĩa là phá hủy. Nhưng có lẽ áp dụng trong es6 thì mang nghĩa phân giải thì đúng hơn. Đây là một kỹ thuật giúp chúng ta tạo ra các variable bằng cú pháp ngắn gọn, bớt lặp code hơn. Hãy cùng đi vào ví dụ sau:
Destructuring Object
const animal = {
dog: 'James',
cat: {
bigger: 'Anthony',
smaller: 'Mimi'
},
turtle: 'Knox'
}
// normal way
const dog = animal.dog;
const cat = animal.cat;
const turtle = animal.turtle;
//es6 - destructuring
const {dog, turtle} = animal;
const {bigger, smaller} = animal.cat;
console.log(dog, turtle); //James, Knox
console.log(bigger, smaller); //Anthony, Mimi
Thực hiện gán tên và gán giá trị mặc định trong Destructuring
Ta dùng dấu :
để gán tên khác cho biến khi không muốn dùng tên trùng với property của object.
và dùng dấu =
để gán giá trị mặc định. Ở đây tôi không hề khai báo giá trị cho publish bên trong dictionary, nên publish sẽ nhận một giá trị mặc định cho nó là '2017-01-10'.
const dictionary = {
subject: {
farmily: {
farther: 'cha',
mother: 'mẹ',
son: 'con trai'
},
city: {
house: 'nhà cửa',
road: 'đường đi',
'traffic light': 'đèn giao thông'
}
},
quantity: 200,
title: 'James Nguyen Dictionary'
}
const {subject: sub, quantity: quan, publish: pub = '2017-01-10'} = dictionary;
console.log(quan); // 200
console.log(publish); //2017-01-10
console.log(pub); //2017-01-10
Destructuring Array
Ở trên, ta đã được thấy Destructuring áp dụng với object. Ngoài ra thì kĩ thuật này còn áp dụng được với cả array nữa. Cách thức áp dụng thì tương tự.
const itCompany = ['framgia', 'evolable', 'fpt'];
const [japan, america, vietnam] = itCompany;
console.log(japan); //framgia
console.log(america); //evolable
console.log(vietnam); //itCompany
Có một vài khác biệt khi ta sử dụng Destructuring với Object
và Array
. Khi sử dụng với Object, các biến được khai báo sẽ tương ứng với property của Object
bị Destructuring, còn với Array
thì các biến được khai báo sẽ tương ứng với các vị trí.
Nhìn vào ví dụ trên, ta thấy là variable japan
sẽ tương ứng với phần tử ở vị trí đầu tiên của Array itCompany
nên nó sẽ nhận giá trị là framgia
. Khác biệt thứ 2 là syntax
. Với Object, ta sử dụng dấu dóng mở ngoặc nhọn: {}
, còn với Array, ta sử dụng ngoặc vuông.
Destructuring Function
Ngoài ra, bạn cũng có thể thực hiện Destructoring với function:
function showInfor({firstName, lastName, age}) {
return `Name: ${firstName} ${lastName} <br/> Age: ${age}`;
}
const person = {
firstName: 'james',
lastName: 'nguyen',
age: 18
}
showInfor(person);
//Name: james nguyen
//Age: 18
Có thể thấy việc sử dụng Destructuring với function sẽ rất tiện lợi khi ta sử dụng function đó nhiều lần và biến truyền vào ở dạng object.
Đặc biệt khi tôi làm việc với React JS, state
và props
rất hay được sử dụng và cả 2 đều là object. Khi này muốn sử dụng bất cứ object nào trong state
hoặc props
, tôi chỉ việc áp dụng destructuring
vào function và truyền state
hoặc props
vào là xong.
Dưới đây là một ví dụ khác khi ta return multiple value.
function operate(a, b) {
return {
sum: a + b,
sub: a - b,
mul: a * b
};
}
const {sum, mul, sub} = operate(20, 10);
console.log(sum, sub, mul); //30, 10, 200
Spread Operator
Spread Operator: ...
là một toán tử nhận các item bên trong một iterable object (tức là các object có thể loop được như Array, nodes, DOM, hoặc thậm chí là một object có iterator) và apply các item này vào containing object.
Khái niệm hơi khó hiểu, nên hãy cùng nhìn vào ví dụ sau đây:
const android = [ 'galaxy s7', 'nokia 1020', 'xiaomi mi5'];
const iphone = ['iphone 7 ', 'iphone8', 'iphone9'];
const phones = [...android, ...iphone, 'viettel phone 100'];
console.log(phones);
//[ 'galaxy s7', 'nokia 1020', 'xiaomi mi5', 'iphone 7 ', 'iphone8', 'iphone9', 'viettel phone 100'];
Ở đây, iterable object chính là android
và iphone
, các item bên trong các Array này đã được apply vào containing object là phones
.
Và lưu ý là các item trong phones
và các item trong android
, iphone
là riêng biệt. Tức là spread operator thực hiện clone chứ không đơn thuần là copy các value này. Chính vì vậy nếu ta thay đổi giá trị galaxy s7
bên trong phones
, thì giá trị galaxy s7
trong android
sẽ không bị thay đổi gì. Vì 2 variable
này là 2 biến tham chiếu khác nhau.
Một lưu ý khác, và đã được tôi nhắc đến ở trên, đó là spread operator
sử dụng được với tất cả iterator, tức là bao gồm cả string, nodes, DOM objects. Ví dụ với string chẳng hạn:
const str = 'Hello';
const strArray = [...str];
console.log(strArray);
//["H", "e", "l", "l", "o"]
Ngoài ra, spread operator còn có một ứng dụng khác gọi là rest params. Hãy cùng đi vào ví dụ sau đây:
const people = ['Tahei', 'Tran Duc Thang', 'Nguyen My Hanh', 'Nguyen Phuc Luong'];
const [CEO, CFO, ...staffs] = people;
console.log(CEO); // Tahei
console.log(CFO); //Tran Duc Thang
console.log(staffs); // ['Nguyen My Hanh', 'Nguyen Phuc Luong'];
Khi sử dụng spread operator với biến staffs
thì nó sẽ nhận tất cả các item còn lại trong people
kể từ item Nguyen My Hanh
trở đi.
for of vs for in
for of
mới được sử dụng trong es6 còn for in
thì đã được sử dụng trong javascript từ trước. for of
giống với spread operator, cũng chỉ sử dụng được với các iterable object. (Muốn biết object nào là iterable, thì bạn hãy console.log nó ra, nếu thấy có prototype là Symbol.iterator
tức là có thể sử dụng được với for of
hoặc spread operator ...
.
const currencies = ['Dong', 'USD', 'euro', 'yuan'];
for (const index in currencies) {
console.log(index, currencies[index]);
}
// 0 Dong
// 1 USD
// 2 euro
// 3 yuan
for (const value of currencies) {
console.log(value);
}
// Dong
// USD
// euro
// yuan
for of
bao gồm cả key, value:
for (const [index, value] of currencies.entries()) {
console.log(value);
}
// 0 Dong
// 1 USD
// 2 euro
// 3 yuan
for of
khá là đa năng khi nó có thể thực hiện loop với Array
, Object
, DOM nodes
. Nhưng nếu bạn đã quen thuộc với vòng lặp for
thông thường hoặc forEach
thì cũng không nhất thiết phải thay đổi làm gì. Các nội dung mà mình đề cập, được liệt kê theo mức độ sử dụng trong project từ nhiều tới thấp. Nói cách khác, mình cũng thi thoảng mới động tới for of
chứ không phải lúc nào loop cũng dùng nó, mà mình thường dùng với map
, filter
, find
hơn (jquery, lodash).
Array Methods
Mình giới thiệu ra đây 6 method mới của Array. 2 cái đầu tiên đó là Array.from()
và Array.of()
. Mục đích của 2 function này đều là để convert các object khác thành Array. Ví dụ như khi mình get 1 list các posts từ server về chẳng hạn. Dữ liệu ở dạng JSON. Vậy thì sẽ không thể sử dụng được các function kèm theo với Array như push, shift hay map được. Giải pháp rất đơn giản: ném listPost
đó vào Array.from(listPost)
, ta sẽ thu được 1 Array chính hiệu với đầy đủ method ta cần.
const numberArr = Array.of(1, 2, 30, 50, 100);
console.log(numberArr); //[1, 2, 30, 50, 100]
2 method tiếp là Array.find
và Array.findIndex
. 2 method này giống với method filter
trong jquery, khác biệt là Array.find
sẽ chỉ trả lại item đầu tiên nó cho là đúng chứ không phải là trả lại mảng các item thỏa mãn điều kiện, cách làm việc tương tự với Array.findIndex
, nhưng findIndex
sẽ chả lại index
của item.
const people = [
{name: 'james', age: 18},
{name: 'Anthony', age: 23},
{name: 'Hanh America', age: 29}
]
const james = people.find(value => value.name == 'james');
const jamesIndex = people.findIndex(value => value.name == 'james');
console.log(james); //Object {name: "james", age: 18}
console.log(jamesIndex); //0
2 method cuối là Array.some
và Array.every
, cả 2 đều sẽ check xem các item trong Array thỏa mãn 1 điều kiện nào đó hay không, nếu tất cả đều thỏa mãn thì Array.every
sẽ trả lại true còn nếu có ít nhất 1 thì Array.some
sẽ trả lại true
, các trường hợp còn lại là false
.
Nhưng thực sự ứng dụng của 2 method này khá ít, và cho tới giờ mình vẫn chưa dùng tới nên về chi tiết sẽ để các ban tự tìm hiểu.
class
Thực chất thì class
không thay đổi nhiều ở trong ES6 so với javascript. Nếu có thì chỉ là các thay đổi nho nhỏ để code sảng sủa và clear hơn thôi. ES6 bổ sung thêm 1 vài prototype method như set
, get
, khai báo function, async, generator ngắn gọn hơn.
class Dog extens Animal {
constructor(name) {
super(name);
this.bark = "GO GO";
}
set setName(name) {
return this.name = name.toUpperCase();
}
get getName() {
return this.name;
}
static information() {
return "Call without init";
}
}
Lời kết
Ngoài những nội dung được đề cập trên, còn các khái niệm khác mà tôi không đề cập đến như promise, symbol, generator, ... các bạn có thể google để biết thêm. Cám ơn đã đọc đến dòng này của bài viết, mỗi comment hoặc up vote đều sẽ là nguồn động lực rất lớn để tôi thực hiện các bài viết khác, thú vị hơn nên mong các bạn đừng ngại . Hẹn gặp lại vào một ngày gần nhất. Thanks.
All rights reserved