Hi all, trong phạm vi bài viết bài này mình xin tóm tắt một số cái mới của ES6 so với ES5. Hiện tại thì các trình duyệt vẫn chưa hỗ trợ ES6, Firefox thì chỉ mới hỗ trợ một số thôi. Nên các bạn muốn vọc thử thì cần phải include cái thư viện này nhé : https://facebook.github.io/react/js/jsfiddle-integration-babel.js
1 . Bàn về Array
Chắc hẳn chúng ta đã quá quen thuộc với nó rồi phải không ? ES6 cung cấp một loạt các API rất hữu dụng với cấu trúc Array. Các xử lý cũng linh hoạt lên rất nhiều, trong đó nổi bật nhất phải kể đến Array Comprehension. Dưới đây là cách viết hàm bình phương cho ES5 và ES6:
// ES5
[1, 2, 3].map(function (i) { return i * i }); // [1, 4, 9]
// ES6
[for (i of [1, 2, 3]) i * i]; // [1, 4, 9]
Một ví dụ nữa với hàm lọc (filter)
// ES5
[1, 2, 3].filter(function (i) { return i < 3 });
// ES6
[for (i of [1, 2, 3]) if (i < 3) i ];
Nếu kết hợp 2 vòng for thì ta sẽ còn viết được nhiều xử lý hơn trong 1 dòng duy nhất
[for (x of 'abc'.split('')) for (y of '123'.split('')) (x+y)];
// ["a1", "a2", "a3", "b1", "b2", "b3", "c1", "c2", "c3"]
Với những sức mạnh kể trên thì bạn sẽ cảm thấy ES6 cũng “mạnh mẽ” chẳng kém gì Python, Haskell hay Scala !
2. Từ khóa let
ES6 giới thiệu một từ khóa mới để định nghĩa biến:
let
. Vậy so với var
thì let
có những khác biệt nào ?var
có hiệu lực đến hàm gần nhất, trong khilet
có hiệu lực đến dấu đóng mở ngoặc gần nhất (thường sẽ nhỏ hơn phạm vi của hàm gần nhất)
Sự khác biệt sẽ thể hiện rõ khi chạy một vòng loop qua một biến khai báo bằng
var
vàlet
var arr = [];
for (var i=0; i<3; i++){
arr[i] = function(){
console.log(i);
}
};
arr[0](); // 3
arr[1](); // 3
arr[2](); // 3
Ở trên là đoạn code của ES5, biến
i
là biến chung trong cả function, vì vậy ở thời điểm gọi arr[0]()
,arr[1]()
, arr[2]()
thì i
đã nhận giá trị 3
, dẫn đến mọi ouput đều trờ thành 3. Dưới đây chúng ta sẽ thử với let
của ES6let arr = [];
for(let i=0; i<3; i++) {
arr[i] = function() {
console.log(i);
}
};
arr[0](); //0
arr[1](); //1
arr[2](); //2
Biến
i
chỉ nhận giá trị trong vòng for
, vì vậy sẽ lần lượt mang giá trị 0,1,2 với 3 lần gọi ở cuối cùng.
3. Arrow Function
Ở 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);
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)); } };
4. 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
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
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);
5. Cải tiến syntax class và object
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.'); } }
6. 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 forEachhơ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ớifor…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);
7. 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}?`);
Babel.js
Babel.js là tool cuối cùng mình muốn giới thiệu với mọi người. Trong thời gian ES6 vẫn chưa chính thức ra mắt và được các browser support, thì các bạn có thể viết code ES6 và dùng Repl của BabelJS để dịch lại sang mã ES5 chạy được trên browser. BabelJSmang lại khả năng phát triển và sử dụng các tính năng của ES6 ngay tại thời điểm này và chỉ cần thêm một thao tác compile là code sẽ chạy được trên các browser bình thường.
Nhân tiện, dưới đây là đoạn code được BabelJS dịch ra với cách dùng hàm
let
bên trên. Bạn có thể thấy biến i
được wrap trong một function mới.var arr = [];
var _loop = function (i) {
arr[i] = function () {
console.log(i);
};
};
for (var i = 0; i < 3; i++) {
_loop(i);
};
arr[0]();
arr[1]();
arr[2]();
Vậy đã có bạn nào code bằng ES6 chưa
This is a very nice article. thank you for publishing this. i can understand this easily.!!.. Ruby on Rails Online Course
ReplyDelete