Điểm lại những tính năng sắp có của Javascript trong ECMAScript 2022 (ES13)

Điểm lại những tính năng sắp có của Javascript trong ECMAScript 2022 (ES13)

Tin ngắn hàng ngày dành cho bạn
  • Zod 4 vừa được giới thiệu với rất nhiều cải tiến về hiệu năng. Cho những ai chưa biết thì Zod là thư viện xác thực dữ liệu đầu vào tập trung vào hiệu năng và API thân thiện với lập trình viên.

    Xem qua thì toàn thấy x7, x9, x17, x100... lần tốc độ của phiên bản trước 😅

    » Xem thêm
  • Hé lộ cách mà độc giả 2coffee.dev đọc bài viết trong tương lai 🫣

    » Xem thêm
  • Microsoft đã quyết định "biến" Windows Subsystem for Linux (WSL) trên Windows thành dự án mã nguồn mở 👏

    Cái đợt còn ham chơi game trên máy tính, sao mà ghét cay ghét đắng Ubuntu thế. Chắc vì do nó không cài được game. Mà làm lập trình dùng mấy cái nhân Linux thì bao sướng. Thế là rơi vào thế tiến thoái lưỡng nan. Muốn dùng Linux nhưng lại phải là Windows.

    Cái Microsoft tung ra WSL này như một vị cứu tinh cần thiết. Hay ho phết. Đơn giản là dùng được lệnh Linux trên Windows thôi. Cơ mà vẫn chưa hoàn toàn "ngon" như hệ điều hành thật. Giờ họ open-source nó rồi, hy vọng sẽ cải tiến nhiều hơn nữa 🙏

    microsoft/WSL

    » Xem thêm

Vấn đề

Đến hẹn lại lên, kể từ năm 2016 ECMAScript đã cam kết mỗi năm sẽ phát hành một phiên bản của Javascript với những cải tiến và thêm những tính năng mới. Đến hiện tại là năm 2022 và chúng ta sắp có những tính năng gì? Hãy cũng điểm lại một số điểm nổi bật nhé.

Private slots

Javascript đã hỗ trợ cú pháp kiểu khai báo Class đã lâu tuy nhiên vẫn còn nhiều thiếu sót. Một trong những tính năng ES13 mang tới sẽ là thuộc tính private của Class.

class Person {
  #name;

  getName() {
      return this.#name;
  }

  setName(name) {
      this.#name = name;
  }
}

Với Private slots bạn sẽ không thể tự do truy cập vào thuộc tính name nữa mà phải thông qua get/set.

const p = new Person();
p.setName('2coffee.dev');
p.name; // undefined
p.getName(); // 2coffee.dev

Ngoài ra bạn có thể sử dụng hàm Object.hasOwn để xác định xem một Class có chứa một thuộc tính private xác định hay không.

Object.hasOwn(Person, 'name'); // true

Top-level await

Nếu như trước kia bạn muốn sử dụng await thì bắt buộc phải sử dụng trong một hàm async thì bây giờ bạn đã có thể sử dụng await ở bên ngoài async (top-level).

async function fetchData() {
  const resp = await fetch('https://jsonplaceholder.typicode.com/users');
  return resp.json();
}
fetchData();

# Bây giờ thì
const resp = await fetch('https://jsonplaceholder.typicode.com/users');
resp.json();

Ngoài ra tính năng này rất hữu ích với cú pháp import, như chúng ta đã biết import được thực hiện một cách bất đồng bộ giúp cho việc "tải" module nhanh hơn nhưng lại có một hạn chế là chúng ta phải viết nhiều mã hơn để đợi cho đến khi module được tải xong mới có thể sẵn sàng sử dụng các hàm có ở trong đó. Với ES13 cú pháp import sẽ hoạt động "như" đồng bộ bằng việc dùng Promise.all cho tất cả import.

Giả sử hai module first.mjs và second.mjs có export các hàm bất đồng bộ ví dụ như:

# first.mjs
async function first() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('first');
    }, 1000);
  });
}

export default first();

Sau đó sử dụng hai module trên:

import { first } from './first.mjs';
import { second } from './second.mjs';
console.log(first, second);

# sẽ tương tương như
import { promise as firstPromise, first } from './first.mjs';
import { promise as secondPromise, second } from './second.mjs';
export const promise = (async () => {
  await Promise.all([firstPromise, secondPromise]);
  console.log(first, second);
})();

Error Cause

Error cause là một cách tiếp cận mới về việc truy vết xử lý lỗi trong Javascript.
Hãy nhìn vào lấy dữ liệu sau của tôi:

const fetchData = async () => {
  return await fetch(url)
    .catch(err => {
       // Bạn sẽ làm gì với err?
    })
}

Bạn sẽ làm gì với err? Console.log ra err và ném (throw) ra một message thông báo "lấy dữ liệu thất bại"!?

const fetchData = async () => {
  return await fetch(url)
    .catch(err => {
       console.log(err);
       throw new Error('lấy dữ liệu thất bại');
    })
}

Khi gọi hàm fetchData mà có lỗi ta sẽ nhận được new Error('lấy dữ liệu thất bại') mà không thể nhận được err, đặc biệt nếu sử dụng fetchData lồng trong nhiều catch thì việc truy vết lỗi sẽ khó khăn bởi vì kết quả nhận được là một thông báo lỗi khác mà ta mong muốn chứ không phải là một err.

Giờ đây với ES13 bạn có thể sử dụng Error Cause để vừa đẩy ra new Error('lấy dữ liệu thất bại'), vừa đính kèm luôn cả err:

const fetchData = async () => {
  return await fetch(url)
    .catch(err => {
       throw new Error('lấy dữ liệu thất bại', { cause: err });
    })
}

Khi đó ta có thể lấy ra err trong fetchData theo cách:

try {
  resp = await fetchData();
  ...
} catch(e) {
  console.log('cause', e.cause);
}

Phương thức .at()

Sử dụng phương thức .at() để lấy ra phần tử tại vị trí index được gọi. Đặc biệt sử dụng index âm để lấy vị trí từ phải sang trái.

['a', 'b', 'c'].at(0); // a
['a', 'b', 'c'].at(-1); // c

Áp dụng cho tất cả Array và String.

RegExp match indices

Thêm flag /d vào regex để lấy ra vị trí bắt đầu - kết thúc của chuỗi tìm được. Vị trí này nằm trong thuộc tính indices.

const matchObj = /(a+)(b+)/d.exec('aaaabb');
console.log(matchObj.indices); // [[0, 6], [0, 4], [4, 6]]

Tổng kết

Trên đây là điểm lại một số điểm nổi bật sẽ phát hành trong ECMAScript 2022. Dự kiến ES13 sẽ được phát hành vào khoảng tháng 6/2022. Hãy cập nhật ngay!

Tham khảo:

Cao cấp
Hello

Tôi & khao khát "chơi chữ"

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên ngay!

Bạn đã thử viết? Và rồi thất bại hoặc chưa ưng ý? Tại 2coffee.dev chúng tôi đã có quãng thời gian chật vật với công việc viết. Đừng nản chí, vì giờ đây chúng tôi đã có cách giúp bạn. Hãy bấm vào để trở thành hội viên ngay!

Xem tất cả

Đăng ký nhận thông báo bài viết mới

hoặc
* Bản tin tổng hợp được gửi mỗi 1-2 tuần, huỷ bất cứ lúc nào.

Bình luận (2)

Nội dung bình luận...
Avatar
Tiến Đức2 năm trước

Chỗ error kia hơi khó hiểu nhỉ

Trả lời
Avatar
Xuân Hoài Tống2 năm trước

B đọc kĩ lại xem chẳng qua là mình có thể "gắn" được error kèm trong lúc trả về error thôi :D

Avatar
Trịnh Thị Anh2 năm trước

Có ai đọc mãi mà không hiểu vụ import không ạ? Chắc mỗi t

Trả lời
Avatar
Xuân Hoài Tống2 năm trước

import là một cú pháp nhập một module theo cách bất đồng bộ vào file của bạn, chính vì bất đồng bộ nên trước kia bạn cần phải "chờ" cho mã được import xong hoàn toàn mới bắt đầu dùng được

Avatar
Tùng Nguyễn2 năm trước

import chạy bất đồng bộ, h c dùng await vào thì nó sẽ đồng bộ kiểu thế