
Code Javascript Cực Ngầu Với Các Thủ Thuật Này
Hôm nay mình sẽ giới thiệu với các bạn một số những tips và tricks để giúp bạn code Javascript một cách hiệu quả cũng như “ngầu hơn” giúp tăng năng suất và hiệu quả công việc. 😀 Bắt đầu nhé.
Nhắc đến Front-end chắc chắn không thể bỏ qua được Javascript, một ngôn ngữ mà được đánh giá là khó và cực kì “hack não” nhất là đối với các anh em mới vào nghề. Tuy vậy, không thể phủ nhận được sức mạnh của Javascript đối với Front-end được. Và đây là các thủ thuật hỗ trợ đắc lực cho các lập trình viên khi sử dụng ngôn ngữ này.
1. Loại bỏ các phần tử trùng lặp trong mảng
Các bạn có 1 mảng gồm nhiều phần tử nhưng có 1 vài phần tử bị trùng lặp, bạn không muốn sự xuất hiện của các phần tử trùng lặp đó? Thuật toán bình thường và dễ nhất đó là tạo 1 mảng mới rồi duyệt lần lượt mảng cũ, tại mỗi phần tử kiểm tra xem có trong mảng mới chưa, nếu chưa có thì push vào, có rồi thì bỏ qua. Hmm, cũng khá là đơn giản nhỉ, nhưng chúng ta có 1 cách khác còn nhanh hơn rất nhiều. Bằng cách sử dụng Set
(được giới thiệu từ ES6
) và toán tử ...
, mọi thứ trở nên cực kì dễ dàng như sau:
const arr = [1, 1, 1, 2, 2, 2, 3, 5, 3, 2];
const newArr = [...new Set(arr)];
console.log(newArr); // [ 1, 2, 3, 5 ]
Set
là cấu trúc dữ liệu mà các phần tử trong Set
lúc nào cũng là duy nhất, bằng việc convert mảng ban đầu sang Set
chúng ta sẽ loại bỏ được hết các phần tử trùng lặp, việc còn lại chỉ còn là convert ngược lại Set
này về mảng mà thôi
Chú ý là cách này chỉ áp dụng cho mảng gồm các kiểu dữ liệu nguyên thủy (Number, String, Null, Undefined, Symbol
) . Nếu là 1 mảng các object
thì các bạn có thể tham khảo code snippet số 12
tại đây đây
2. Loại bỏ các falsy values
trong 1 mảng.
Falsy values
trong Javascript bao gồm có 0, false, NaN, undefined, null, ''
(xâu rỗng).
Ngược lại với nó thì ta có khái niệm truthy values
. Trong JavaScript, truthy
là giá trị được hiểu là true
trong ngữ cảnh Boolean. Tất cả mọi giá trị đều là truthy
, trừ các falsy values
kể trên.
Giả sử ta có 1 mảng ban đầu gồm có các falsy values
và truthy
values
, ta muốn loại bỏ toàn bộ các falsy values
chỉ giữ lại các truthy values
thôi. Có rất nhiều cách để thực hiện điều này, hôm nay mình muốn giới thiệu đến các bạn 1 cách làm đơn giản mà hiệu quả nhất đó là sử dụng filter
kết hợp với Boolean
.
const arr = [
0,
false,
NaN,
undefined,
"",
null,
1,
true,
"Hello World",
{ name: "value" },
];
const filteredArr = arr.filter(Boolean);
console.log(filteredArr); // [ 1, true, 'Hello World', { name: 'value' } ]
3. Viết biểu thức điều kiện một cách ngắn gọn và mạnh mẽ hơn.
Ví dụ 1 đoạn code như sau:
const a = 1;
const b = 1;
if (a === b) console.log("a = b");
else console.log("a != b");
ternary operator
để viết 1 cách ngắn gọn hơn như sau:a === b ? console.log("a = b") : console.log("a != b");
console.log(`${a === b ? "a = b" : "a != b"}`);
Có 1 cách khác đó là sử dụng toán tử &&
và ||
.
Giải thích về 2 toán tử &&
và ||
.
Với 1 chuỗi các lựa chọn thì &&
sẽ trả về falsy value đầu tiên trong danh sách, nếu tất cả các toán hạng đều true
thì sẽ trả về toán hạng cuối cùng.
Ví dụ:
const a = 1;
const b = 2;
console.log(a && b); // 2
console.log(0 && 1); // 0
&&
, toán tử ||
sẽ trả về truthy value
đầu tiên trong danh sách, nếu tất cả các toán hạng đều là false
thì sẽ trả về toán hạng cuối cùngconst a = 1;
const b = 2;
console.log(a || b); // 1
console.log(0 || 1); // 1
console.log(`${(a == b && "a = b") || "a != b"}`);
const data = await fetch([api]);
if (data) {
console.log(data.length);
} else {
console.log(0);
}
console.log(data.length || 0);
data.length
là truthy value
thì sẽ lấy giá trị của data.length
, nếu không thì sẽ lấy giá trị 0
. &&
và ||
: const response = {
message: "",
success: true,
result: {
name: "response-list",
list: [1, 2, 3, 4],
},
};
// Lấy giá trị của result
const result = (response && response.result) || "Default result";
// Lấy giá trị của 1 thuộc tính không tồn tại trong object không sử dụng ||
const unknownProperty =
response && response.result && response.result.unknownProperty;
// Lấy giá trị của 1 thuộc tính không tồn tại trong object sử dụng ||
const unknownPropertyWithDefaultValue =
(response && response.result && response.result.unknownProperty) ||
"Default Value";
console.log(result); // { name: 'response-list', list: [ 1, 2, 3, 4 ] }
console.log(unknownProperty); // undefined
console.log(unknownPropertyWithDefaultValue); // "Default Value"
||
trả về falsy value
thì dữ liệu sẽ được gán = []. Đây cũng là 1 điều rất được khuyến khích trong khi làm các sản phẩm thực tế tránh việc ứng dụng của chúng ta gặp các lỗi phát sinh vì dữ liệu trả về không chính xác hoặc không lấy được dữ liệu. Optional Chaning
. Optional Chaning
sử dụng kí tự ? để lấy thuộc tính khi object không phải là null. Optional Chaing
: const response = {
message: "",
success: true,
result: {
name: "response-list",
list: [1, 2, 3, 4],
},
};
// Lấy giá trị của result
const result = response?.result ?? "Default result";
// Lấy giá trị của 1 thuộc tính không tồn tại trong object không sử dụng ||
const unknownProperty = response?.result?.unknownProperty;
// Lấy giá trị của 1 thuộc tính không tồn tại trong object sử dụng ||
const unknownPropertyWithDefaultValue =
response?.result?.unknownProperty ?? "Default Value";
console.log(result); // { name: 'response-list', list: [ 1, 2, 3, 4 ] }
console.log(unknownProperty); // undefined
console.log(unknownPropertyWithDefaultValue); // "Default Value"
??
, về cơ bản thì toán tử ??
khá giống với ||. Ngoại trừ việc nếu || trả về giá trị truthy
đầu tiên thì ??
trả về giá trị defined
đầu tiên. let height = 0;
alert(height || 100); // 100
alert(height ?? 100); // 0
falsy value
. Khi sử dụng || thì kết quả sẽ trả về là 100
do 100
là giá trị truthy
đầu tiên. Còn khi sử dụng ??
thì ta thấy kết quả trả về là 0, bởi vì như mình nói ở trên, ??
lấy giá trị defined đầu tiên và 0 tuy là 1 falsy value
nhưng vẫn là 1 defined value
nên ta có kết quả như trên. ??
tại đây4. Chuyển xâu về số
Chuyển 1 xâu về số có thể được thực hiện một cách nhanh chóng bằng việc sử dụng toán tử cộng +
const strInt = "10";
const number = +strInt;
console.log("number", number); // 10
console.log("typeof number", typeof number); // number
boolean
về number
console.log(+true); // Return: 1
console.log(+false); // Return: 0
Có 1 cách khác nữa là sử dụng ~~
~
thường được biết đến như “bitwsise NOT operator”, ~n = - n - 1
~15 = -16
~
thì ta sẽ có ~~n = -(-n-1)-1 = n.
const strInt = "10";
const number = ~~strInt;
console.log("number", number); // 10
console.log("typeof number", typeof number); // number
~true = -2
và ~false = -1
~~
có 1 số điểm mạnh hơn so với sử dụng +
+
chỉ có thể chuyển đổi các xâu “có dạng số” ví dụ như "11", "12", ....
Nếu giá trị truyền vào k phải là 1 xâu kiểu số hoặc 1 biểu thức ví dụ như: "Hello", x=10
thì việc sử dụng toán tử +
sẽ trả về giá trị là NaN
trong khi ~~
sẽ trả về là 0
. +
sẽ trả vế chính xác giá trị của xâu đó trong khi ~~
trả về giá trị tương đương với Math.floor()
const strArr = ["10", "Str", (x = 23), "false", "10.6"];
strArr.forEach((item) => console.log(+item)); // 10, NaN, NaN, NaN,10.6
strArr.forEach((item) => console.log(~~item)); // 10, 0, 23, 0,10
5. Xáo trộn mảng
const initialArr = [1, 2, 3, 4, 5];
const shuffledArr = initialArr.sort(() => 0.5 - Math.random());
console.log(shuffledArr); // [ 1, 5, 2, 3, 4 ]
6. Sử dụng biến làm thuộc tính của object
Ví dụ:
const propertyName = "Rikikudo";
const object = {
[propertyName]: "Value",
};
console.log("object", object); // object { Rikikudo: 'Value' }
Với cách này, các bạn có thể thay đổi tên thuộc tính của object 1 cách tùy ý dựa theo 1 biến bên ngoài.
7. Object To Array
const arr = [1, 2, 3, 4, 5, 6];
const obj = { ...arr };
console.log(obj); // { '0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6 }
8. Reset Array
Bạn muốn xóa toàn bộ dữ liệu của 1 mảng 1 cách nhanh chóng và dễ dàng? Cực kì đơn giản, chỉ cần 1 câu lệnh sau: arr.length = 0;
var array = [11, 12, 13, 14, 15];
console.log(array.length); // 5
array.length = 0;
console.log(array.length); // 0
console.log(array); // []
9. Tráo đổi giá trị của 2 biến.
let a = 1,
b = 2;
let c = "c",
d = "d";
[a, b] = [b, a];
[c, d] = [d, c];
console.log(`a: ${a}, b: ${b}, c: ${c}, d: ${d}`); //a: 2, b: 1, c: d, d: c
10. Hợp nhất nhiều objects vào 1 object duy nhất
const obj1 = {
a: 1,
b: 2,
};
const obj2 = {
c: 3,
d: 4,
};
const obj3 = {
e: 5,
f: 6,
};
const obj4 = {
g: 7,
h: 8,
};
const obj5 = {
i: 9,
j: 10,
};
const mergedObj = {
...obj1,
...obj2,
...obj3,
...obj4,
...obj5,
};
console.log(mergedObj); //{ a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10 }
Chú ý là khi hợp nhất các objects, nếu trong trường hợp có 2 (hoặc nhiều) objects có cùng thuộc tính thì giá trị của thuộc tính đó sẽ là giá trị gán với thuộc tính của object được hợp nhất sau cùng.
Ví dụ:
const obj1 = {
a: 1,
b: 2,
};
const obj2 = {
c: 3,
d: 4,
};
const obj3 = {
a: 5,
f: 6,
};
const obj4 = {
g: 7,
h: 8,
};
const obj5 = {
a: 9,
j: 10,
};
const mergedObj = {
...obj1,
...obj2,
...obj3,
...obj4,
...obj5,
};
console.log(mergedObj); // { a: 9, b: 2, c: 3, d: 4, f: 6, g: 7, h: 8, j: 10 }
Lời kết
Trên đây mình đã giới thiệu với các bạn 1 số tips và tricks trong Javascript mà mình thấy rất hữu ích. Dù có nhiều ý kiến trái chiều về việc có nên sử dụng 1 số tips và tricks trong bài hay không tuy nhiên cá nhân mình thấy chúng vẫn là những thủ thuật rất hay và có thể được áp dụng vào thực tế đương nhiên là phải biết vận dụng chính xác. 😀 Mong nhận được ý kiến phản hồi và góp ý từ các bạn.
Nguồn tham khảo:
Stackoverflow.com / Dev.to / Medium.com / Javascript.info
Post Comment