Thứ tư, 05/02/2020 | 00:00 GMT+7

Có gì mới trong ECMAScript 2020 (ES2020)


Đã đến lúc cần có một bản cập nhật khác về tác phẩm nghệ thuật luôn thay đổi đó là JavaScript. Trong bài viết này, ta sẽ xem xét một số tính năng mới nhất và tuyệt vời nhất đi kèm với ES2020.

Cài đặt

Vì nhiều người không nghĩ rằng cập nhật trình duyệt của họ để giúp cuộc sống của nhà phát triển của họ dễ dàng hơn, ta cần sử dụng babel để bắt đầu sử dụng các tính năng không có sẵn trên bảng cho user . Vì lý do đơn giản, tôi sẽ sử dụng gói Parcel để mọi thứ chạy nhanh nhất có thể.

$ yarn add parcel-bundler
package.json
"scripts": {
  "start": "parcel index.html"
},

Đáng buồn thay, tại thời điểm viết bài này, ta đã đi quá xa so với thời đại và dường như không có cài đặt trước hoạt động cho ES2020. Nếu bạn ném những thứ này vào file .babelrc và lưu, Parcel sẽ xử lý việc cài đặt mọi thứ cho bạn.

.babelrc
{
  "plugins": [
    "@babel/plugin-proposal-nullish-coalescing-operator",
    "@babel/plugin-proposal-optional-chaining",
    "@babel/plugin-proposal-class-properties",
    "@babel/plugin-proposal-private-methods",
    "@babel/plugin-syntax-bigint"
  ]
}

Biến lớp riêng

Một trong những mục đích chính của các lớp là chứa mã của ta thành các module có thể tái sử dụng nhiều hơn. Vì bạn sẽ tạo một lớp được sử dụng ở nhiều nơi khác nhau, bạn có thể không muốn mọi thứ bên trong nó có sẵn trên phạm vi global .

Bây giờ, bằng cách thêm một ký hiệu băm đơn giản vào trước biến hoặc hàm của ta , ta có thể dành chúng hoàn toàn để sử dụng nội bộ bên trong lớp.

class Message {
  #message = "Howdy"

  greet() { console.log(this.#message) }
}

const greeting = new Message()

greeting.greet() // Howdy
console.log(greeting.#message) // Private name #message is not defined

Promise.allSettled

Khi ta đang làm việc với nhiều lời hứa, đặc biệt là khi chúng phụ thuộc vào nhau, có thể hữu ích khi ghi lại những gì đang xảy ra với từng lời hứa để gỡ lỗi. Với Promise.allSettled , ta có thể tạo một lời hứa mới chỉ trả về khi tất cả các lời hứa được chuyển cho nó đã hoàn tất. Điều này sẽ cung cấp cho ta quyền truy cập vào một mảng với một số dữ liệu trên mỗi lời hứa.

const p1 = new Promise((res, rej) => setTimeout(res, 1000));

const p2 = new Promise((res, rej) => setTimeout(rej, 1000));

Promise.allSettled([p1, p2]).then(data => console.log(data));

// [
//   Object { status: "fulfilled", value: undefined},
//   Object { status: "rejected", reason: undefined}
// ]

Nhà điều hành Nullish Coalescing

Bởi vì JavaScript được nhập động, bạn cần lưu ý việc xử lý các giá trị true / falsy của JavaScript khi gán các biến. Nếu ta có một đối tượng với một số giá trị, đôi khi ta muốn cho phép các giá trị sai về mặt kỹ thuật, như một chuỗi rỗng hoặc số 0. Việc đặt các giá trị mặc định sẽ nhanh chóng gây khó chịu vì nó sẽ overrides lên những giá trị phải là giá trị hợp lệ.

let person = {
  profile: {
    name: "",
    age: 0
  }
};

console.log(person.profile.name || "Anonymous"); // Anonymous
console.log(person.profile.age || 18); // 18

Thay vì dấu ống kép, ta có thể sử dụng toán tử dấu hỏi kép để có kiểu chặt chẽ hơn một chút, điều này chỉ cho phép mặc định khi giá trị là null hoặc không xác định.

console.log(person.profile.name ?? "Anonymous"); // ""
console.log(person.profile.age ?? 18); // 0

Nhà điều hành chuỗi tùy chọn

Tương tự như toán tử liên kết nullish, JavaScript có thể không hoạt động theo cách ta muốn khi xử lý các giá trị sai. Ta có thể trả về một giá trị nếu những gì ta muốn là không xác định, nhưng nếu đường dẫn đến nó là không xác định thì sao?

Bằng cách thêm dấu chấm hỏi trước ký hiệu dấu chấm, ta có thể làm cho bất kỳ phần nào của đường dẫn giá trị trở thành tùy chọn để ta vẫn có thể tương tác với nó.

let person = {};

console.log(person.profile.name ?? "Anonymous"); // person.profile is undefined
console.log(person?.profile?.name ?? "Anonymous");
console.log(person?.profile?.age ?? 18);

Bạn có thể tham khảo bài đăng này để tìm hiểu thêm về Chuỗi liên kết tùy chọn và Kết hợp không rõ ràng.

BigInt

Ta sẽ không đi sâu vào chi tiết kỹ thuật, nhưng vì cách JavaScript xử lý các con số, khi bạn đạt đến mức đủ cao, mọi thứ bắt đầu trở nên khó khăn một chút. Số lớn nhất mà JavaScript có thể xử lý là 2 ^ 53, mà ta có thể thấy với MAX_SAFE_INTEGER .

const max = Number.MAX_SAFE_INTEGER;

console.log(max); // 9007199254740991

Bất cứ điều gì trên mức đó và mọi thứ bắt đầu trở nên hơi kỳ lạ…

console.log(max + 1); // 9007199254740992
console.log(max + 2); // 9007199254740992
console.log(max + 3); // 9007199254740994
console.log(Math.pow(2, 53) == Math.pow(2, 53) + 1); // true

Ta có thể giải quyết vấn đề này với kiểu dữ liệu BigInt mới. Bằng cách ném ký tự ' n ' vào cuối, ta có thể bắt đầu sử dụng và tương tác với những con số cực kỳ lớn. Ta không thể trộn các số chuẩn với các số BigInt, vì vậy bất kỳ phép toán nào cũng cần được thực hiện với BigInts.

const bigNum = 100000000000000000000000000000n;

console.log(bigNum * 2n); // 200000000000000000000000000000n

Nhập động

Nếu bạn có một file chứa đầy đủ các chức năng tiện ích, một số trong số chúng có thể hiếm khi được sử dụng và việc nhập tất cả các phần phụ thuộc của chúng có thể chỉ là một sự lãng phí tài nguyên. Bây giờ ta có thể sử dụng async / await để nhập động các phụ thuộc của ta khi ta cần chúng.

Điều này sẽ không hoạt động với cài đặt Parcel hiện tại của ta , vì ta đang sử dụng nhập khẩu sẽ chỉ hoạt động trong môi trường Node.js.

math.js
const add = (num1, num2) => num1 + num2;

export { add };
index.js
const doMath = async (num1, num2) => {
  if (num1 && num2) {
    const math = await import('./math.js');
    console.log(math.add(5, 10));
  };
};

doMath(4, 2);

Kết luận

Đến đây bạn đã sẵn sàng để bắt đầu một cách tốt hoặc có thể khiến đồng nghiệp của bạn bối rối với các tính năng JavaScript thậm chí chưa có trong hầu hết các trình duyệt (trừ khi chúng có nếu bạn đang đọc nó từ tương lai 😉).


Tags:

Các tin liên quan