Học cú pháp mới là 1 điều kỳ cục. Phần lớn chúng ta chỉ học vừa đủ những cú pháp cần thiết cho công việc. Rồi đến một lúc ta thấy bạn bè/đồng nghiệp/người hướng dẫn code, ta lại thắc mắc tại sao ta lại không biết những thứ hay ho đến thế.
Danh sách dưới đây chỉ gồm 5 cái gạch đầu dòng nho nhỏ mà tôi tin là sẽ giúp cho công việc code của bạn trở nên nhanh hơn.
Và như mọi khi, nếu bài viết này hữu ích, hãy comment và share nhé!
Template literals
Tôi phải thừa nhận rằng tính năng này rất tuyệt. Sẽ chẳng có ai lại làm như thế này...
const concatenatedString = “I am the “ + number + “ person to recommend this article.”
khi mà ta có thể làm như thế này:
const concatenatedString = `I am the ${number} person to recommend this article.`
Tuyệt vời!
Template literal còn cho phép ta gọi 1 function với 1 string.
Xem nhé:
const consoleLogAString = (string) => {
console.log(string)
}
consoleLogAString`I am the string to be logged!`
// I am the string to be logged!
Nói cách khác, cú pháp này:
consoleLogAString('Here is the string!')
hoàn toàn giống với cú pháp này:
consoleLogAString`Here is the string!`
Template literal có thêm những lợi ích: truyền vào cho function 1 mảng các tham số được tách ra từ 1 string. Những tham số này được sắp xếp tuần tự: từ đầu string đến placehoder của biến đầu tiên là phần tử đầu tiên của mảng, rồi cứ thế đến cuối chuỗi.
Hãy xem ví dụ sau để hiểu vấn đề:
function logOutValues(strings, value1, value2) {
console.log(strings, value1, value2)
}
logOutValues`Here is one value: ${1} and two: ${2}. Wow!`
// ["Here is one value: ", " and two: ", ". Wow!"] 1 2
Hoặc điều khiển dữ liệu như ví dụ dưới:
const person = {
name: "Scott",
age: 25
}
function experience(strings, name, age) {
const str0 = strings[0]; // "that "
const str1 = strings[1]; // " is a "
let ageStr = 'youngster';
if (age > 99){
ageStr = 'centenarian';
}
return str0 + name + str1 + ageStr;
}
const output = experience`that ${ person.name } is a ${ person.age }`;
console.log(output);
// that Scott is a youngster
(Cảm ơn Domenico Matteo đã 'clean code' cho phần này)
Tính năng này cũng cho phép bạn nhúng DSL với chuỗi escape (xem thêm ở đây).
Nó hữu dụng như thế nào?
Tính năng này cho phép chúng ta gọi function với các string theo 1 cách rất 'trong sáng'. Hãy cùng đến với ví dụ về thư viện styled_component cho React:
const Title = styled.h1`
font-size: 1.5em;
text-align: center;
color: palevioletred;
`;
Implicit return
Đã bao nhiêu lần bạn viết 1 function trả về 1 giá trị?
const addOne = (num) => {
return num + 1
}
console.log(addOne(1))
// 2
Trả lời: mọi lúc.
Hãy đổi mới với cách implicit return trong ES6:
const addOne = (num) => (
num + 1
)
console.log(addOne(1))
// 2
hay thậm chí là còn rút gọn được hơn nữa:
const addOne = num => num + 1
console.log(addOne(1))
// 2
Nó hữu dụng như thế nào?
Ít code hơn. Dễ đọc hơn.
Tạo động lực cho bạn viết các function nhỏ hơn, do đó bạn có thể tránh được những đoạn code nhiều dòng.
Cuối cùng thì nó cũng khá "đẹp" đấy chứ!
Argument destructure kết hợp với Default argument
Trong trường hợp bạn chưa nghe nói đến Argument destructure thì dưới đây là ví dụ:
const person = { name: 'Scott', attractiveness: 8.5 }
const consoleLogAttributes = ({ name, attractiveness }) => {
console.log(name, attractiveness)
}
consoleLogAttributes(person)
// 'Scott', 8.5
Rất hữu ích! Tuy nhiên nếu ta gọi function mà không truyền tham số vào thì sao?
consoleLogAttributes()
// TypeError: Cannot match against 'undefined' or 'null'.
Không ổn 1 chút nào. Hãy sửa lỗi bằng cách thêm default argument - trong trường hợp này là 1 object rỗng:
const consoleLogAttributes = ({ name, attractiveness } = {}) => {
console.log(name, attractiveness)
}
Bây giờ:
consoleLogAttributes()
// undefined undefined
Nếu gọi hàm mà không truyền tham số thì sẽ không xuất hiện lỗi nữa. Hãy thử thêm 1 vài thứ nữa xem sao...
const consoleLogAttributes = ({
name = 'Default name',
attractiveness = '10'
} = {}) => {
console.log(name, attractiveness)
}
Default ở mọi chỗ! Khi ta viết hàm như trên, kết quả sẽ trả về giống nhau trong cả 2 trường hợp dưới:
consoleLogAttributes()
// 'Default name', 10
consoleLogAttributes({})
// 'Default name', 10
Nó hữu dụng như thế nào?
Function bạn viết sẽ báo lỗi đầu vào hơn do nó đã được sửa để đáp ứng các biến đầu vào dạng undefine.
Một điểm trừ đó là nó làm cho function trở nên rườm rà hơn, tuy nhiên nếu so với điểm lợi của nó thì quả thực không đáng kể.
Property value shorthand
Hãy sử dụng lại object person phía trên. Đây là 1 pattern thông dụng - bạn có 1 biến và bạn muốn gán cho 1 key giá trị của biến đó:
const name = "Scott"
const person = { name: name }
// { name: "Scott" }
ES6 làm cho nó trở nên đơn giản hơn nhiều:
const name = "Scott"
const person = { name }
// { name: "Scott" }
Thử nó với nhiều biến hơn xem nào:
const name = "Scott"
const programmingAbility = "poor"
const person = { name, programmingAbility }
// { name: "Scott", programmingAbility: "poor" }
Thử nó với function luôn:
const name = “Scott”
const sayName = function() { console.log(this.name) }
const person = { name, sayName }
// { name: “Scott”, sayName: function() { console.log(this.name) } }
Sao không thử khai báo function ngay trong khai báo object nhỉ?
const name = “Scott”
const person = { name, sayName() { console.log(this.name) } }
// { name: “Scott”, sayName: function() { console.log(this.name) } }
Nó hữu dụng như thế nào?
Rất ngắn gọn: code ngắn và "sạch" hơn.
Map()
Giả sử bạn có 1 object với 100 cặp key - value, bạn muốn lặp qua mỗi phần tử và log ra giá trị của nó.
Thông thường bạn sẽ làm theo cách này:
const targetObject = { 1: 'one', 2: 'two' }
Object.keys(targetObject).forEach(key => {
console.log(targetObject[key])
}
// 'one'
// 'two'
Trông không khả quan cho lắm. Đấy là còn chưa tính đến việc bạn không thể trực tiếp lặp qua các thuộc tính của 1 object.
Tuy nhiên nó chỉ còn là dĩ vãng:
const map = new Map([[1, 'one'][2, 'two']])
map.forEach(val => {
console.log(val)
}
// 'one'
// 'two'
Ở trên ta tạo 1 map bằng cách truyền vào constructor của 1 mảng các cặp key - value.
map sẽ có dạng:
Map(2) {1 => "one", 2 => "two"}
Bạn có thể truy cập và thay đổi giá trị của chúng bằng get và set:
map.get(1)
// 'one'
map.set(3, 'three')
// Map(3) {1 => "one", 2 => "two", 3 => "three"}
Bạn cũng có thể sử dụng các method của array như forEach và lặp qua các giá trị của map. Công việc cũng rất dễ dàng khi bạn muốn lấy kích thước 1 map.
const objectSize = Object.keys(object).length
const mapSize = map.size
Một điều cuối cùng là bạn có thể sử dụng bất cứ cái gì để làm key cho map, không giống như với object: ngày, function, object,... Do đó bạn hoàn toàn có thể có 1 map với key là ngày, value là dữ liệu tương ứng với ngày đó.
Nó hữu dụng như thế nào?
Map hoạt động như object, với các chức năng của 1 array.
Điều này giúp cho code "sạch" hơn, đơn giản hơn khi lập trình viên cần phải làm việc với object thuần - cấu trúc của nó cũng rất tốt với các lệnh set và get.
Map cũng rất thoải mái khi cho phép bạn làm việc với mọi kiểu key, giúp cho bạn tùy biến dễ hơn rất nhiều.
Bài viết được dịch từ: https://engineering.musefind.com/five-es6-features-to-make-your-life-easier-8c6a9518219f
Bình luận