Series JavaScript sida – Cùng làm quen và “chịch”, nhầm… nghịch ES6

Dạo gần đây mình đi làm thêm, project hiện tại có sử dụng React với cả ES6 – chuẩn Javascript mới. Do mấy bài viết trước mình chê JavaScript sida nhiều thấy cũng tội, hôm nay viết một bài nói tốt cho nó một tí để đổi gió nhé.

Phiên bản JavaScript hiện tại chúng ta đang sử dụng dựa trên chuẩn ECMAScript 5 (ES5). Hiện tại, JavaScript được sử dụng ngày càng nhiều, từ front-end cho đến back-end, điều này đòi hỏi sự cải tiến trong JavaScript (Nghĩ cũng đúng, cái ngôn ngữ sida thế mà code mấy hệ thống to to, code phức tạp thì để lâu chả banh chành ra à !!). Đó là lý do chuẩn ECMAScript 6 (ES6) ra đời, cung cấp 1 số tính năng mới cho JavaScript, đồng thời giúp code trở nên tường minh và dễ viết hơn.

Capture

Trong phạm vi bài viết, mình sẽ giới thiệu một số tính năng mới của ES6 và mổ xẻ so sánh nó với ES5 (Mình chỉ giới thiệu 1 số tính năng hay thôi nhé, các bạn tham khảo nguồn dưới cuối bài để tìm hiểu thêm). Để chạy được ES6 phải ta setup hoặc add thư viện hơi rắc rối, biết các bạn lười mình đã chuẩn bị sẵn 1 link jsfiddle hỗ trợ ES6 cho các bạn, các bạn cứ vào mà nghịch code ES6 thoải mái thôi: https://jsfiddle.net/jwtg7a1g/.

Tính năng nào cảm thấy hay mình sẽ đặt lên đầu tiên nhé. Bắt đầu nào!!

1. Arrow (Lambda Expression)

Ở ES6, thay vì khai báo function như kiểu thông thường, ta đã có thể sử dụng =>. Cách khai báo này tương tự như Lambda Expression trong C#, giúp cho code tường minh và ngắn gọn hơn rất rất nhiều.

var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Giả sử ta muốn tìm các số chẵn
// Cách viết cũ
var odd = numbers.filter(function(n) { return n % 2 == 1 });
console.log(odd);
// Với arrow
odd = numbers.filter(n => n % 2 == 1);
console.log(odd);

view raw
arrow.es6.js
hosted with ❤ by GitHub

Ngoài ra, nhờ có arrow, ta không còn bị tình trạng this bị bind nhầm như trước kia nữa.

var person = {
firstName: 'Hoang',
friends : ['Minh', 'Sang', 'Khoa', 'Hoang'],
showFriend: function() {
this.friends.forEach(function(fr) {
// Với cách viết cũ, this ở đây sẽ là object window, không phải person
console.log(this.firstName + ' have a friend named ' + fr);
});
// Ta sử dụng arrow, this vẫn là object person
this.friends.forEach(fr => console.log(this.firstName + ' have a friend named ' + fr));
}
};

view raw
no_more_this.js
hosted with ❤ by GitHub

2. Default parameter, destructuring, spread operator

Default parameter đã có từ lâu trong C#, giờ JavaScript cũng đã có nhưng… Java vẫn chưa có. Nhờ default parameter, ta có thể xác định giá trị mặc định của tham số truyền vào

// Cách cũ, phải check tham số truyền vào rồi xác định giá trị
function multiply(a, b) {
var b = typeof b !== 'undefined' ? b : 1;
return a*b;
}
// Với ES6, chỉ cần sử dụng dấu =
function multiply(a, b = 1) {
return a*b;
}
multiply(5); // 5

view raw
default_param.js
hosted with ❤ by GitHub

Destructuring cũng là một tính năng khá hay, nó cho phép ta “phân rã” các phần tử trong 1 array hoặc 1 object

// Với array
var foo = ["one", "two", "three"];
// Cách cũ
var one = foo[0];
var two = foo[1];
var three = foo[2];
// Dùng destructuring
var [one, two, three] = foo;
// Với object
var obj = {firstName:'Hoang', lastName:'Pham'};
// Cách cũ
var firstName = obj.firstName;
var lastName = obj.lastName;
// Dùng destructuring
var {firstName, lastName} = obj;
// Nếu muốn lấy tên biến khác tên field của object
var {firstName : fn, lastName : ln} = obj; //fn: Hoang, ln: Pham

view raw
destructuring.js
hosted with ❤ by GitHub

Một tính năng mới khác mà mình cảm thấy khá thú vị đó là spread operator, tính năng này cho phép chuyển đổi qua lại giữa 1 array và danh sách các params. Nghe hơi khó hiểu nhỉ, nhìn code là hiểu ngay.

function f(x,y) {
// y ở đây là array, chứa ["hello", true, false]
return x * y.length;
}
f(3, "hello", true, falser) == 9;
// Cách gọi này tương tự với f(3, ["hello", true, false])
function f(x, y, z) {
return x + y + z;
}
f([1,2,3]) == 6;
// Cách gọi này tương tự với f(1, 2, 3);

view raw
rest_operator.js
hosted with ❤ by GitHub

3. Cải tiến syntax class và object

Lần trước, mình đã chửi thằng JavaScript sida vì nó chẳng có class gì sất, mà phải dùng prototype. Chắc nghe chửi nhiều quá nên các bác cũng sợ, giờ đã phải thêm class vào ES6. Trong ES6, class có hỗ trợ constructor, get/set, việc kế thừa cũng rất dễ thực hiện bằng từ khóa extends.

class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(this.name + ' makes a noise.');
}
}
class Dog extends Animal {
speak() {
console.log(this.name + ' barks.');
}
}

view raw
class.js
hosted with ❤ by GitHub

Với cách khai báo object mới, ta có thể viết code một cách ngắn gọn và rõ ràng hơn nhiều. Mình là mình lười code lắm, viết code càng ít mình càng khoái.

var firstName = 'Hoang';
var lastName = 'Pham';
// Khai báo object kiểu cũ
var obj = {
firstName: firstName,
lastName: lastName,
showName: function() { console.log(this.firstName + ' ' + this.lastName) }
};
// Khai báo kiểu mới, ngắn gọn hơn
// Không cần lặp lại tên biến hay function
var obj = {
firstName,
lastName,
showName() { console.log(this.firstName + ' ' + this.lastName) }
};

view raw
object.js
hosted with ❤ by GitHub

4. Iterator

Ngày xưa, để duyệt qua từng phần tử trong một mảng, ta phải sử dụng hàm for, chạy index từ 0 tới cuối mảng. Về sau đỡ hơn, ta có thể sử dụng hàm forEach. Tuy nhiên nhiều người lại thấy cú pháp hàm forEach hơi lạ, không được tự nhiên cho lắm. Trong ES6, ta đã có thêm for… of để duyệt từng phần tử trong một mảng (Đừng nhầm với for…in, để duyệt các trường trong 1 object nhé).

var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// Cách cũ, duyệt từ đầu
for(var i = 0; i< numbers.length; i ++)
{
console.log(number[i]);
}
// Dùng forEach
numbers.forEach(function(number) {
console.log(number);
})
// Dùng for…of, dễ viết dễ đọc
for(var number of numbers) console.log(number);

view raw
for.js
hosted with ❤ by GitHub

5. Template String

Chức năng này khá giống chức năng string interpolation trong C# 6.0. Trước đây, JavaScript không có string.format, do đó ta phải cộng chuỗi bằng tay rất cực. Giờ đây, sử dụng template string, ta không cần phải mất công cộng chuỗi nữa, code rõ ràng hơn nhiều.

var name = "Bob", time = "today";
// Cách cũ
console.log("Hello " + name + " how are you " + time + " ?");
// Dùng string interpolation, để ý dấu `
console.log(`Hello ${name}, how are you ${time}?`);

view raw
template_string.js
hosted with ❤ by GitHub

6. Map và Set

Nhắc lại một chút kiến thức cơ bản: Map là cấu trúc dữ liệu cho phép ta lưu dữ liệu dưới dạng Key-Value, Set là một mảng mà trong đó không có phần tử nào trùng nhau (Bạn nào quên thì lật sách Cấu trúc dữ liệu và thuật toán ra xem lại nhé). Giờ ES6 đã bổ sung thêm 2 cấu trúc dữ liệu này, giúp việc code được dễ dàng hơn.

// Sets
var s = new Set();
s.add("hello").add("goodbye").add("hello");
s.size === 2;
s.has("hello") === true;
// Maps
var m = new Map();
m.set("hello", 42);
m.set(s, 34);
m.get(s) == 34;

view raw
map_set.js
hosted with ❤ by GitHub

7. Promise

Promise là một khái niệm khá hay, giúp cho việc viết code asynchonous (bất đồng bộ) dễ dàng hơn. Promise được sử dụng trong rất nhiều thư viện như jQuery, AngularJS. Lần khác có thời gian mình sẽ viết bài nói rõ hơn về khái niệm này, còn hiện tại các bạn qua blog của bạn mình xem tạm nhé: Tìm hiểu về promise.

// Code from: http://www.html5rocks.com/en/tutorials/es6/promises/
var promise = new Promise(function(resolve, reject) {
// do a thing, possibly async, then…
if (true) {
resolve("Stuff worked!");
}
else {
reject(Error("It broke"));
}
});
promise.then(function(result) {
console.log(result); // "Stuff worked!"
}, function(err) {
console.log(err); // Error: "It broke"
});

view raw
promise.js
hosted with ❤ by GitHub

 

Có thể thấy, ES6 đã làm JavaScript bớt sida hơn nhiều. Tuy nhiên, ES6 vẫn còn một khuyết điểm, đó là nó chưa được hỗ trợ hầu hết các trình duyệt. IE và Chrome không thể chạy trực tiếp ES6 được, Firefox thì chỉ chạy được 1 số tính năng: https://kangax.github.io/compat-table/es6/.

(Update 08/02/2017: Hiện tại phần lớn các tính năng của ES6 đã chạy được trên Microsoft Edge, Firefox, Chrome và Safari phiên bản mới nhất rồi nhé).

Dù vậy, hiện tại nhiều công ty đã áp dụng ES6 vào code. Lập trình viên viết code ES6 như thường, sau đó sử dụng babel/traceur để dịch code EcmaScript 6 sang EcmaScript 5 (Project hiện tại của mình cũng vậy, cứ viết code ES6 xong nó tự build ra JavaScript ES5, khá sướng). Trong tương lai vài năm nữa, khi các trình duyệt đã hỗ trợ đầy đủ, ta có thể viết ES6 và chạy thẳng trên trình duyệt luôn.

Trong phạm vi bài viết, mình không thể nêu hết toàn bộ các cải tiến của ES6 được. Bạn nào có hứng thú có thể tham khảo thêm ở một số nguồn dưới đây:

2 thoughts on “Series JavaScript sida – Cùng làm quen và “chịch”, nhầm… nghịch ES6”

  1. Chào anh,
    anh cho em hỏi ES6 này chỉ sử dụng được trên node.js thôi hả. Em thấy bài viết hay thì tìm hiểu thì thấy set up toàn dùng lệnh npm không. Không thấy dùng để include vào html

    Liked by 1 person

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s