Tóm gọn JavaScript es6 trong 10 phút

2057

JavaScript es6 hay còn được biết đến với cái tên là es2015 (do được ra đời vào năm 2015), hay một số người còn gọi nó là JavaScript 6. Trong bài viết này để ngắn gọn thì mình sẽ gọi là es6.

JavaScript es6 ra đời vào năm 2015 và bổ sung thêm một số tính năng đáng chủ ý sau:

  • Sử dụng let để khai báo biến
  • Sử dụng const để khai báo hằng
  • Arrow function (xin phép không Việt hóa)
  • Sử dụng class để khai báo lớp
  • Được phép khai báo giá trị mặc định cho tham số
  • Array.find()
  • Array.findIndex()
  • Toán tử ** (lũy thừa)

Chúng ta sẽ cùng nhau đi tìm hiểu lần lượt từng cú pháp một nhé.

1. Sử dụng let để khai báo biến

Chúng ta vẫn quen với việc khai báo biến với từ khóa var. Tuy nhiên nếu được khai báo với từ khóa var thì biến đó sẽ trở thành biến toàn cục, và khi nó thay đổi giá trị thì sẽ thay đổi cả bên ngoài block code.

Block code là phạm vi nằm trong một cặp dấu {} bất kỳ.

Xét ví dụ khai báo biến với từ khóa var sau để hiểu rõ hơn.

var x = 10;

{
    var x = 2;
    console.log(x); // 2
}

console.log(x); // 2

Để khắc phục điều này thì Javascript es6 đã bổ sung thêm hình thức khai báo biến với từ khóa let.

Biến được khai báo với từ khóa let sẽ chỉ có phạm vi trong một block code.

Bạn có thể xem ví dụ sau để hiểu rõ hơn.

let x = 10;
let y = 20;

if (true) {
    let x = 1;

    // Kết quả là 1, vì x đã được khai báo lại
    console.log(x); 

    // Kết quả là 20, do y được khai báo từ đầu là 20
    console.log(y);
}

// Kết quả là 10,
// do x mặc dù được khai báo lại là 1 trong câu lệnh if trên
// nhưng biến x đó chỉ có phạm vi trong câu lệnh if
console.log(x); // 10

// Kết quả vẫn là 20
console.log(y); // 20

Một ví dụ khác

if (true) {
    let x = 10;
}

// Sẽ nhận được lỗi
// error: Uncaught ReferenceError: x is not defined
// Do biến x chỉ có tác dụng trong phạm vi câu lệnh if
console.log(x); 

Bạn cũng không thể khai báo hai biến giống nhau với từ khóa let

let x = 10;
let x = 10; // Uncaught SyntaxError: Identifier 'x' has already been declared

2. Sử dụng const để khai báo hằng

Từ phiến bản es6, JavaScript cho phép bạn khai báo hằng với từ khóa const. Cung tương tự với let, hằng số khai báo với const chỉ có phạm vi trong một block code.

const PI = 3.14;
if (true) {
    const PI = 3.141;
    console.log(PI); // 3.141
}

console.log(PI); // 3.14

Sau khi khai báo hằng, giá trị của hằng sẽ KHÔNG thể bị thay đổi.

const PI = 3.14;
PI = 3.141; // error: Uncaught Error: "PI" is read-only

Bạn cũng KHÔNG thể khai báo một hằng trước, rồi mới gán giá trị sau:

const PI; // Uncaught SyntaxError: Missing initializer in const declaration
PI = 3.141;

Cách khai báo hằng chính xác nhất

const PI = 3.14;

Tuy nhiên, nếu hằng là một đối tượng, thì giá trị của các thuộc tính có thể thay đổi được.

const me = {
  firstName: "Binh",
  lastName: "Pham",
  score: 10
}

console.log(me.score); // 10

// Thay đổi score thành 100
me.score = 100;
console.log(me.score); // 100

Nhưng bạn không thể gán lại toàn bộ đối tượng:

const me = {
  firstName: "Binh",
  lastName: "Pham",
  score: 10
}

const me = {
  firstName: "Minh",
  lastName: "Pham",
  score: 10
} // Uncaught SyntaxError: Identifier 'me' has already been declared

3. Arrow function

JavaScript es6 bổ sung thêm cú pháp arrow function (Hàm mũi tên), chi tiết được thể hiện qua ví dụ sau:

// Cách khai báo hàm thông thường
var hello = function() {
  return "Hello World!";
}

// Khai báo với arrow function
var hello = () => {
  return "Hello World!";
}

// Mặc định arrow function sẽ return giá trị
// Nên đối với function hello return một string "Hello World!"
// Thì có thể viết ngắn gọn thành
var hello = () => "Hello World!";

Việc hỗ trợ thêm cú pháp arrow function, sẽ giúp bạn viết các các callback tiện, “đẹp”, ngắn gọn hơn. Cùng xem ví dụ dưới đây để hiểu rõ:

var numbers = [1, 2, 3, 4]

// Không sử dụng arrow function
var doubleNumbers = numbers.map(function (number) {
  return number * 2;
});

console.log(doubleNumbers); // [2, 4, 6, 8]

// Sử dụng arrow function
var doubleNumbers = numbers.map(number => number * 2);

console.log(doubleNumbers) // [2, 4, 6, 8]

Việc viết callback ngắn gọn hơn đó chưa phải là tất cả, arrow function còn làm thay đổi this so với cách viết function trước kia nữa.

Với arrow function, this sẽ được hiểu là đối tượng khai báo nó.

Cùng xem ví dụ dưới đây để hiểu:

function main () {
  this.level = 2;

  let numbers = [1, 2, 3, 4];

  // Không sử dụng arrow function
  var self = this;
  var increments = numbers.map(function (number) {
    // Nếu bạn viết this.level
    // thì nó sẽ đi tìm thuộc tính level nằm trong cái callback này
    // chứ không phải là thuộc tính level của function main
    // vì thế mà mình đã khai báo một biến self = this ở bên ngoài callback
    // với mục đích để truy xuất được tới giá trị của level
    // mà mình khai báo ở function main

    return number * self.level;
  });

  console.log(increments); // 2, 4, 6, 8]

  // Sử dụng arrow function
  var increments = numbers.map(number => {
    // Với arrow function, this sẽ được hiểu là đối tượng khai báo nó
    // Trong trường hợp này chính là function main
    // Nên ta có thể dễ dàng lấy được thuộc tính level thông qua cú pháp this.level

    return number * this.level;
  });

  console.log(increments); // 2, 4, 6, 8]
}

main();

4. Sử dụng class để khai báo lớp

JavaScript es6 bổ sung thêm cú pháp để bạn có thể khai báo class dễ dàng hơn. Mình đã có một bài viết chi tiết về vấn đề này, bạn có thể tham khảo:

>> Tham khảo: Lập trình hướng đối tượng trong JavaScript.

5. Array.find()

Array.find() được sử dụng để tìm kiếm phần tử đầu tiên trong mảng thỏa mãn điều kiện. Điều kiện được thể hiện dưới dạng một callback, callback trả về true có nghĩa là thỏa mãn, ngược lại trả về false.

var numbers = [4, 9, 19, 25, 29];
var first = numbers.find(function (number) {
  return number > 18
});

console.log(first); // 19

callback sẽ nhận 3 tham số:

  • Tham số 1: Giá trị của phần tử
  • Tham số 2: Chỉ số (vị trí, index) của phần tử
  • Tham số 3: Là bản thân cái Array đang thực hiện

6. Array.findIndex()

Tương tự với Array.find(), nhưng thay vì trả về phần tử đầu tiên, thì Array.findIndex() sẽ trả về vị trí của phần tử đầu tiên thỏa mãn điều kiện. Nếu không có phần tử nào thỏa mãn điều kiện thì phương thức sẽ trả về -1.

var numbers = [4, 9, 19, 25, 29];
var firstIndex = numbers.findIndex(function (number) {
  return number > 18
});

console.log(firstIndex); // 2

7. Toán tử ** (lũy thừa)

Toán tử lũy thừa (số mũ) được thể hiện như trong ví dụ sau:

var x = 5;
var y = x ** 2; // x mũ 2
console.log(y); // 25

8. Một số tính năng khác

8.1 Bổ sung thuộc tính & phương thức của đối tượng Number

Các thuộc tính được bổ sung bao gồm:

  • Number.EPSILON: Mình chưa hiểu ý nghĩa của thuộc tính này. Hiện đang có giá trị là 2.220446049250313e-16
  • Number.MIN_SAFE_INTEGER: Giá trị nhỏ nhất của kiểu integer trong JavaScript, hiện đang có giá trị là -9007199254740991
  • Number.MAX_SAFE_INTEGER: Giá trị lớn nhất của kiểu integer trong JavaScript, hiện đang có giá trị là 9007199254740991

Các phương thức được bổ sung bao gồm:

  • Number.isInteger(): Kiểm tra một giá trị có thuộc kiểu integer hay không.
  • Number.isSafeInteger(): Kiểm tra một giá trị có phải kiểu integer và nằm giữa khoảng Number.MIN_SAFE_INTEGERNumber.MAX_SAFE_INTEGER hay không.

Ví dụ:

Number.isInteger(10); // returns true
Number.isInteger(10.5); // returns false

Number.isSafeInteger(10); // returns true
Number.isSafeInteger(12345678901234567890); // returns false

8.2 Bổ sung thêm một số hàm toàn cục

Các hàm được bổ sung bao gồm:

  • isFinite(): Kiểm tra một giá trị có phải hữu hạn hay không. Trả về false nếu giá trị đó là Infinity hoặc NaN, ngược lại trả về true.
  • isNaN(): Kiểm tra một giá trị có phải là NaN hay không, nếu đúng thì trả về true, ngược lại trả về false.

Infinity là kiểu dữ liệu thể hiện sự vô hạn, như phép chia một số với số 0. NaN (Not a Number) kiểu dữ liệu không phải là số.

isFinite(10/0);       // returns false
isFinite(10/1);       // returns true

isNaN("Hello");       // returns true

9. Tổng kết

Trên là tất tần tật sự thay đổi của phiên bản es6 so với phiên bản JavaScript trước đó. Riêng với hằng số Number.EPSILON thì mình vẫn chưa hiểu rõ ý nghĩa của nó, nhưng mình đoán là nó ít khi được sử dụng thôi, bằng chứng là mình chưa bao giờ sử dụng nó cả và cũng chưa nghe thấy ai đó nhắc về nó cho tới khi mình viết bài viết này.

Trong quá trình code javascript, thì mình đánh giá có 4 tính năng mang giá trị nhiều nhất trong đợt cập nhật này là: let, const, arrow function, class. Số còn lại thì ít giá trị hơn, do thứ nhất là ít được sử dụng, thứ hai là nếu cần sử dụng thì vẫn có cách khác thay thế. Không biết các bạn thì thế nào.

Chúc các bạn học tập hiệu quả.