What's new in ES8
Bài đăng này đã không được cập nhật trong 7 năm
ES8 (tên chính thức là ES2017) vừa mới được chính thức release cuối tháng trước. Nếu bạn còn nhớ thì ES5 được release từ tận năm 2009. Vậy mà chỉ trong 3 năm qua, spec của ECMAScript đã được update đến 3 lần, và năm sau có lẽ cũng sẽ không khác. Như thế đã đủ để thấy sự trỗi dậy thần kì của JavaScript trong những năm gần đây. Hãy cùng tìm hiểu xem chúng ta có gì mới trong năm nay nhé. Nếu bạn đang dùng Google Chrome (version 59) thì bạn có thể mở DevTool ra và thử ngay những tính năng mới này.
String padding
prototype
của String
có thêm 2 function mới String.prototype.padStart
và String.prototype.padEnd
. Syntax của 2 function mới này như sau
str.padStart(targetLength [, padString])
str.padEnd(targetLength [, padString])
2 function này dùng để pad phần đầu hoặc cuối một String
với kí tự trong argument padString
đến độ dài targetLength
. Giá trị mặc định của padString
là khoảng trắng.
Ví dụ
'abc'.padStart(6); // ' abc'
'abc'.padStart(6, '-'); // '--abc'
'abc'.padEnd(6); // 'abc '
'abc'.padEnd(6, '-'); // 'abc--'
Object API
Lần này API của Object
có thêm vài function như sau
Object.values
Từ ES6, chúng ta đã có Object.keys
để dễ dàng lấy toàn bộ key của một object. Bây giờ chúng ta sẽ có thêm Object.values
để lấy toàn bộ value của một object. Cách dùng cũng tương tự như Object.keys
Object.values(obj)
Ví dụ
Object.values({
a: 'apple',
b: 'boy',
c: 'cat',
d: 'dog'
}); // ['apple', 'boy', 'cat', 'dog']
Object.entries
Object.entries
thì là một sự kết hợp giữa Object.keys
và Object.values
. Nó sẽ return tất cả cặp key
và value
của object. Syntax của nó cũng giống hệt 2 cái kia
Object.entries(obj)
Ví dụ
Object.entries({
a: 'apple',
b: 'boy',
c: 'cat',
d: 'dog'
}); // [['a', 'apple'], ['b', 'boy'], ['c', 'cat'], ['d', 'dog']]
Object.getOwnPropertyDesriptors
Cái này thì cũng gần giống với Object.getOwnPropertyDescriptor
đã có từ cả tỉ năm trước. Nhưng thay vì chỉ trả về miêu tả cho 1 thuộc tính thì Object.getOwnPropertyDesriptors
sẽ cho miêu tả tất cả thuộc tính của một object (trừ các thuộc tính thừa kế từ prototype
). Các giá trị của miêu tả có thể bao gồm value
, writable
, get
, set
, configurable
, enumerable
. Syntax của nó như sau
Object.getOwnPropertyDesriptors(obj)
Ví dụ
Object.getOwnPropertyDesriptors({a: 1, b: 2});
Kết quả sẽ là
{
a: {
configurable: true,
enumerable: true,
value: 1,
writable: true
},
b: {
configurable: true,
enumerable: true,
value: 2,
writable: true
},
}
Function này sẽ dùng khi bạn muốn thực sự clone một thuộc tính của object, tức là cả getter
và setter
của nó.
Ví dụ bạn có object
const a = {
name: 'John Smith',
set name(value) {
store.dispatch('NAME_CHANGING', name, value)
this.name = value
}
}
Nếu bạn muốn extend object này, dùng Object.assign
thì sẽ chỉ có giá trị của thuộc tính name
được copy thôi. Nếu bạn muốn copy cả setter
của nó thì phải làm thế này
const b = Object.create(
Object.getPrototypeOf(a),
Object.getOwnPropertyDescriptors(a)
);
Nếu bạn định viết một Framework mới thì cái này có thể sẽ hữu ích nhỉ.
Function arguments/parameters list trailing comma
Cũng giống như array và object, bây giờ bạn có thể viết dấu phẩy ở cuối phần khai báo tham số cho function hoặc các giá trị truyền vào khi gọi function.
Ví dụ
const s = (a, b,) => a + b; // No SyntaxError anymore
s(1, 2,); // 3. No SyntaxError anymore
Nếu bạn cần truyền một đống giá trị cho một function (như function ga
của Google Analytics chẳng hạn) thì cái này có thể sẽ giúp bạn tách các giá trị thành nhiều dòng dễ chịu hơn một chút
someFunction(
firstArg,
secondArg,
thirdArg,
fourthArg,
);
Async/await
Tính năng này đã được mọi người bàn đến từ rất lâu rồi, có thể bạn cũng đang sử dụng tính năng này trong các project hiện tại rồi. Nếu bạn từng làm việc với C# thì syntax này có lẽ khá quen thuộc với bạn. Với syntax này, bạn có thể viết các đoạn code asynchronous theo kiểu synchronous, nghĩa là không cần Promise
hay callback function.
Ví dụ một đoạn code dùng Promise
thế này
function getContent = () => getContentFromServer()
.then(() => {
this.setContent(content);
// do other things with content here
})
.catch((error) => {
// handle error
});
Khi viết bằng async/await
thì sẽ thế này
async function getContent() {
try {
const content = await getContentFromServer();
this.setContent(content);
// do other things with content here
return content;
} catch (error) {
// handle error
}
}
Thật ra async function cũng sẽ return một Promise
. Và cái mà bạn await
thật ra cũng là một Promise
hoặc một async function
khác. Vậy nên tính năng này thật ra là một syntax tiện lợi hơn cho Promise
. Vậy nên tốt nhất bạn nên hiểu về Promise trước khi dùng đến syntax này. Nhưng nếu bạn không có vấn đề gì với Promise thì đây là một tính năng rất tuyệt vời.
Tất nhiên vì nó return một Promise nên bạn cũng có thể dùng nó như một Promise
Promise.all([getContent(), someOtherAsyncFunction()]]);
Shared memory and atomics
Tính năng này được thêm vào để các thread (main thread, web worker) có thể cùng truy cập một dữ liệu (read/write).
Một object SharedArrayBuffer
sẽ được dùng để biểu diễn dữ liệu này. Syntax để tạo một SharedArrayBuffer như sau
new SharedArrayBuffer(length) // length, in bytes, is the size of the buffer to create
Ví dụ
const buffer = new SharedArrayBuffer[1024]
Để truy cập dữ liệu này, ta dùng đến object Atomics
. Object này có các static method để thay đổi dữ liệu trong một SharedArrayBuffer. Nó sẽ đảm bảo các thao tác lên dữ liệu được thực hiện lần lượt, không bị gián đoạn. Bạn có thể xem các static method của Atomic
ở đây. Dưới đây là một ví dụ sử dụng SharedArrayBuffer và Atomics
// worker.js
onmessage = (event) => {
doSomething(event.data.sab)
}
const doSomething = (sab) => {
const ta = new Uint8Array(sab);
Atomics.add(ta, 0, 12); // returns 0, the old value
Atomics.load(ta, 0); // 12
}
// main thread
const sab = new SharedArrayBuffer(1024);
const worker = new Worker('worker.js');
worker.postMessage({ sab })
Lifting template literal restriction
Đây là một tính năng đã có mặt trong final proposal nhưng không có mặt trong đợt update này. Có thể nó sẽ được thêm vào trong ES9. Hiện giờ cũng chỉ có mỗi Firefox (53) hỗ trợ tính năng này. Ngắn gọn thì bây giờ bạn đã có thể dùng Tagged template literals. Tag là một function để parse template literal. Tóm lại là một syntax thuận tiện và linh hoạt hơn cho template literal.
Dưới đây là một ví dụ hoàn chỉnh (MDN)
var person = 'Mike';
var age = 28;
function myTag(strings, personExp, ageExp) {
var str0 = strings[0]; // "that "
var str1 = strings[1]; // " is a "
// There is technically a string after
// the final expression (in our example),
// but it is empty (""), so disregard.
// var str2 = strings[2];
var ageStr;
if (ageExp > 99){
ageStr = 'centenarian';
} else {
ageStr = 'youngster';
}
return str0 + personExp + str1 + ageStr;
}
var output = myTag`that ${ person } is a ${ age }`;
console.log(output);
// that Mike is a youngster
Things that didn't make it
Có một vài thứ khá thú vị có mặt trong proposal nhưng không xuất hiện trong lần update này. Mình rất hy vọng là nó sẽ có mặt trong lần update tới
All rights reserved