5 bí quyết viết JS conditionals tốt hơn
Note: This post is over 7 years old. The information may be outdated.
Trong Javascript, chúng ta phải sử dụng nhiều loại lệnh điều kiện (if ... else ...) khác nhau, sau đây là 5 bí quyết để viết lệnh if else nhanh hơn và chuyên nghiệp hơn.
1. Sử dụng Array.includes thay cho điều kiện so sánh bằng (==)
Hãy xem ví dụ:
// condition
function test(fruit) {
if (fruit == 'apple' || fruit == 'strawberry') {
console.log('red')
}
}
Nhìn sơ qua, ví dụ trên có vẻ không vấn đề gì. Tuy nhiên, sẽ có vấn đề gì khi chúng ta có thêm 50 cái so sánh bằng liên tiếp thì sao?
Bạn có thể viết lại câu điều kiện trên dưới dạng:
function test(fruit) {
// extract conditions to array
const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries']
if (redFruits.includes(fruit)) {
console.log('red')
}
}
2. Less Nesting, Return Early
Ý nghĩa của Less Nesting, Return Early là hạn chế việc lồng quá nhiều câu điều kiện, mà hãy return sớm nhất ngay khi có thể.
Ví dụ đoạn chương trình như sau:
function test(fruit, quantity) {
const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries']
// condition 1: fruit must has value
if (fruit) {
// condition 2: must be red
if (redFruits.includes(fruit)) {
console.log('red')
// condition 3: must be big quantity
if (quantity > 10) {
console.log('big quantity')
}
}
} else {
throw 'No fruit!'
}
}
// test results
test(null) // error: No fruits
test('apple') // print: red
test('apple', 20) // print: red, big quantity
Với đoạn code trên, 1 quy luật đơn giản là hãy return ngay khi có thể:
function test(fruit, quantity) {
const redFruits = ['apple', 'strawberry', 'cherry', 'cranberries']
if (!fruit) throw 'No fruit!' // condition 1: throw error early
if (!redFruits.includes(fruit)) return // condition 2: stop when fruit is not red
console.log('red')
// condition 3: must be big quantity
if (quantity > 10) {
console.log('big quantity')
}
}
3. Sử dụng tham số mặc định trong function (default function parameters) và Detructuring
Ví dụ với đoạn code sau, trong ES5 chắc hẳn bạn đã từng phải rất khó chịu khi luôn phải check xem giá trị của tham số trong function có phải là null / undefined hay không.
function test(fruit, quantity) {
if (!fruit) return
const q = quantity || 1 // if quantity not provided, default to one
console.log(`We have ${q} ${fruit}!`)
}
//test results
test('banana') // We have 1 banana!
test('apple', 2) // We have 2 apple!
Với ES6 về sau, bạn đã có thể gán giá trị mặc định cho params, như sau:
function test(fruit, quantity = 1) {
// if quantity not provided, default to one
if (!fruit) return
console.log(`We have ${quantity} ${fruit}!`)
}
//test results
test('banana') // We have 1 banana!
test('apple', 2) // We have 2 apple!
Chúng ta cũng có thể gán default cho fruit
, như sau: function test(fruit = "unknown", quantity = 1) {...}
Nhưng trong trường hợp muốn fruit
là object thì sao? Chúng ta có thể gán giá trị default cho nó hay không?
function test(fruit) {
// printing fruit name if value provided
if (fruit && fruit.name) {
console.log(fruit.name)
} else {
console.log('unknown')
}
}
//test results
test(undefined) // unknown
test({}) // unknown
test({ name: 'apple', color: 'red' }) // apple
Trong ví dụ trên, chúng ta muốn in fruit name ra nếu tồn tại, ngược lại in 'unknown'
. Chúng ta có thể tránh việc sử dụng fruit && fruit.name
bằng cách sử dụng default function parameter và destructing.
// destructing - get name property only
// assign default empty object {}
function test({ name } = {}) {
console.log(name || 'unknown')
}
//test results
test(undefined) // unknown
test({}) // unknown
test({ name: 'apple', color: 'red' }) // apple
Khi cần thuộc tính name trong object fruit
, ta destruct sử dụng {name}
, sau đó sử dụng biến name
trong function thay vì fruit.name
4. Sử dụng Map / Object Literal thay vì lệnh switch
Xem ví dụ sau, chúng ta muốn in tên fruit thông qua màu sắc:
function test(color) {
// use switch case to find fruits in color
switch (color) {
case 'red':
return ['apple', 'strawberry']
case 'yellow':
return ['banana', 'pineapple']
case 'purple':
return ['grape', 'plum']
default:
return []
}
}
//test results
test(null) // []
test('yellow') // ['banana', 'pineapple']
Code trên không có gì sai, nhưng nó quá dài dòng try hard, mình viết lại dưới dạng trí tuệ hơn 1 chút:
function test(color) {
// use object literal to find fruits in color
const fruitColor = {
red: ['apple', 'strawberry'],
yellow: ['banana', 'pineapple'],
purple: ['grape', 'plum'],
}
return fruitColor[color] || []
}
Mặc khác bạn có thể sử dụng Map trong Javascript ES2015 (cho phép lưu trữ key-value):
function test(color) {
// use Map to find fruits in color
const fruitColor = new Map()
.set('red', ['apple', 'strawberry'])
.set('yellow', ['banana', 'pineapple'])
.set('purple', ['grape', 'plum'])
return fruitColor.get(color) || []
}
Còn 1 cách khác nữa là sử dụng Array.filter
:
function test(color) {
// use Array filter to find fruits in color
const fruits = [
{ name: 'apple', color: 'red' },
{ name: 'strawberry', color: 'red' },
{ name: 'banana', color: 'yellow' },
{ name: 'pineapple', color: 'yellow' },
{ name: 'grape', color: 'purple' },
{ name: 'plum', color: 'purple' },
]
return fruits.filter((f) => f.color == color)
}
5. Sử dụng Array.every & Array.some
Một tip nữa là JS hỗ trợ nhiều thao tác trên array giúp giảm thiểu rất nhiều số dòng code. Ví dụ bên dưới kiểm tra có phải mọi fruit
đều là màu đỏ hay không:
function test(fruits) {
const fruits = [
{ name: 'apple', color: 'red' },
{ name: 'banana', color: 'yellow' },
{ name: 'grape', color: 'purple' },
]
let isAllRed = true
// condition: all fruits must be red
for (let f of fruits) {
if (!isAllRed) break
isAllRed = f.color == 'red'
}
console.log(isAllRed) // false
}
Ngắn gọn hơn, mình sử dụng Array.every
function test(fruits) {
const fruits = [
{ name: 'apple', color: 'red' },
{ name: 'banana', color: 'yellow' },
{ name: 'grape', color: 'purple' },
]
// condition: short way, all fruits must be red
const isAllRed = fruits.every((f) => f.color == 'red')
console.log(isAllRed) // false
}
Array.some
kiểm tra array xem có ít nhất 1 phần tử nào đó điều kiện hay không.
function test(fruits) {
const fruits = [
{ name: 'apple', color: 'red' },
{ name: 'banana', color: 'yellow' },
{ name: 'grape', color: 'purple' },
]
// condition: if any fruit is red
const isAnyRed = fruits.some((f) => f.color == 'red')
console.log(isAnyRed) // true
}
Hy vọng với các bí quyết trên sẽ giúp code JS của các bạn sẽ clean & clear hơn. Bài viết dịch từ bài viết gốc từ: https://scotch.io/tutorials/5-tips-to-write-better-conditionals-in-javascript