javascript viết gọn

Hơn 25 kỹ thuật Viết gọn JavaScript tuyệt vời

Kỹ thuật viết gọn JavaScript: Hướng dẫn toàn diện

Với sự tiếp tục phát triển của JavaScript, phong cách viết mã của chúng ta cũng trở nên tinh gọn hơn. Một trong những lĩnh vực thể hiện điều này là kỹ thuật viết tắt, không chỉ giúp mã của bạn gọn gàng hơn mà còn có thể cải thiện hiệu suất. Trong bài viết này, chúng ta sẽ đi sâu vào hơn 25 kỹ thuật viết tắt để tối ưu hóa hành trình JavaScript của bạn.

Nếu bạn có bất kỳ câu hỏi nào, đừng ngần ngại liên hệ với chúng tôi.

Kỹ thuật viết tắt cho Điều kiện

Điều kiện là một cấu trúc cơ bản trong JavaScript, cho phép ra quyết định trong mã. Các kỹ thuật viết tắt có thể làm cho các điều kiện này trở nên gọn gàng hơn mà không làm mất đi tính rõ ràng.

Toán tử Ternary

Một phương án thay thế cho cấu trúc if-else tiêu chuẩn mà trả về một giá trị dựa trên một điều kiện.

				
					// Longhand
let result;
if (x > 10) {
    result = "greater";
} else {
    result = "lesser";
}


// Shorthand
const result = x > 10 ? "greater" : "lesser";

				
			
  • Các trường hợp sử dụng: Hữu ích cho việc ra quyết định đơn giản trong mã, khi một giá trị được gán dựa trên một điều kiện.

  • Hiệu suất: Hiệu suất gần như giống với if-else nhưng cung cấp cú pháp gọn gàng hơn cho việc ra quyết định đơn giản.

  • Khả năng tương thích: Được hỗ trợ trên tất cả các trình duyệt hiện đại.

Kiểm tra giá trị Truthy và Falsy

Trong JavaScript, các giá trị như 0, null, undefined, NaN, "" là “falsy”. Tất cả các giá trị khác là “truthy”. Đặc điểm này có thể được sử dụng để tạo ra các kỹ thuật viết tắt.

				
					// Longhand
if (value !== null && value !== undefined && value !== "") {
    // Code
}


// Shorthand
if (value) {
    // Code
}

				
			
  • Các trường hợp sử dụng: Kiểm tra sự tồn tại hoặc hiệu lực của một biến trước khi tiếp tục.

  • Hiệu suất: Nhanh hơn một chút do ít kiểm tra hơn, nhưng cần nhớ về các giá trị truthy và falsy của JavaScript.

  • Khả năng tương thích: Được hỗ trợ trên mọi nơi.

Đánh giá Short-Circuit

Sử dụng OR logic || và AND logic && để trả về một giá trị hoặc thực thi một hàm nếu một điều kiện nhất định là đúng.

				
					// Longhand
if (value) {
    executeFunction();
}


// Shorthand
value && executeFunction();

				
			
  • Các trường hợp sử dụng: Thực hiện nhanh các hàm hoặc gán giá trị dựa trên điều kiện.

  • Hiệu suất: Hiệu suất tương tự nhưng cung cấp cú pháp gọn gàng hơn.

  • Khả năng tương thích: Được hỗ trợ trên mọi nơi.

Toán tử Nullish Coalescing (??)

Toán tử nullish coalescing (??) là một toán tử logic trả về toán hạng ở phía bên phải khi toán hạng ở phía bên trái là null hoặc undefined, và ngược lại trả về toán hạng ở phía bên trái.

				
					// Longhand
let response;
if (data === null || data === undefined) {
    response = "Default";
} else {
    response = data;
}


// Shorthand
const response = data ?? "Default";

				
			
  • Các trường hợp sử dụng: Đặt giá trị mặc định cho các biến có thể là null hoặc undefined.

  • Hiệu suất: Hiệu suất tương tự nhưng cung cấp cú pháp cụ thể và gọn gàng hơn so với ||.

  • Khả năng tương thích: Được hỗ trợ trong ES11 (ES2020) trở lên, có thể không có sẵn trên các trình duyệt cũ hơn mà không cần một trình biên dịch.

Dấu chấm hỏi tùy chọn (?.)

Toán tử dấu chấm hỏi tùy chọn (?.) cho phép đọc giá trị của một thuộc tính trong một chuỗi các đối tượng được kết nối mà không cần kiểm tra xem mỗi tham chiếu trong chuỗi có hợp lệ hay không.

				
					// Longhand
let value;
if (obj && obj.nestedObj && obj.nestedObj.property) {
    value = obj.nestedObj.property;
}


// Shorthand
const value = obj?.nestedObj?.property;

				
			
  • Các trường hợp sử dụng: Truy cập an toàn vào các thuộc tính của đối tượng lồng nhau mà không cần kiểm tra từng cấp độ về sự tồn tại.

  • Hiệu suất: Nhanh hơn một chút trong các tình huống với sự lồng nhau sâu do ít kiểm tra hơn.

  • Khả năng tương thích: Được hỗ trợ trong ES11 (ES2020) trở lên, có thể không có sẵn trên các trình duyệt cũ hơn mà không cần một trình biên dịch.

Toán tử Gán Logic

Toán tử gán logic kết hợp các toán tử logic (&&, ||, hoặc ??) với biểu thức gán.

				
					// Longhand
if (x) {
    x = y;
}


// Shorthand
x &&= y;

				
			
  • Các trường hợp sử dụng: Gán một giá trị cho một biến dựa trên giá trị hiện tại của biến đó.

  • Hiệu suất: Hiệu suất rất tương tự, chủ yếu là sự tiện ích về cú pháp.

  • Khả năng tương thích: Được hỗ trợ trong ES12 (ES2021) trở lên, có thể không có sẵn trên các trình duyệt cũ hơn mà không cần một trình biên dịch.

Kiểm tra Nhiều Điều Kiện

Trong các tình huống mà một biến cần được kiểm tra với nhiều giá trị.

				
					// Longhand
if (value === 1 || value === 2 || value === 3) {
    // Do something
}


// Shorthand
if ([1, 2, 3].includes(value)) {
    // Do something
}

				
			
  • Các trường hợp sử dụng: Kiểm tra nếu một giá trị tồn tại trong một danh sách có sẵn của các khả năng.

  • Hiệu suất: Viết tắt có thể chậm hơn một chút đối với mảng rất lớn, nhưng cung cấp cú pháp gọn gàng hơn.

  • Khả năng tương thích: Phương thức includes được hỗ trợ trong ES7 (ES2016) và trở lên.

Sử dụng `in` để Kiểm tra Thuộc Tính

Thay vì sử dụng typeof hoặc nối thuộc tính để kiểm tra nếu một đối tượng chứa một thuộc tính nhất định, bạn có thể sử dụng toán tử in.

				
					// Longhand
if (obj && "property" in obj) {
    // Do something
}


// Shorthand
if ("property" in obj) {
    // Do something
}

				
			
  • Các trường hợp sử dụng: Kiểm tra nếu một đối tượng có một thuộc tính cụ thể mà không lo lắng về chuỗi nguyên mẫu.

  • Hiệu suất: Toán tử in hiệu quả và gọn gàng, đặc biệt khi không chắc chắn nếu chính đối tượng đó đã được xác định.

  • Khả năng tương thích: Được hỗ trợ rộng rãi trong các phiên bản JavaScript.

Switch Case với Object Literals

Thay vì sử dụng một câu lệnh switch, bạn có thể sử dụng một object literal để ánh xạ các trường hợp với các hàm tương ứng của chúng, làm cho mã nguồn gọn gàng và dễ đọc hơn.

				
					// Longhand
switch (key) {
    case 'a':
        doSomethingA();
        break;
    case 'b':
        doSomethingB();
        break;
    default:
        doDefault();
}


// Shorthand
const actions = {
    'a': doSomethingA,
    'b': doSomethingB,
    'default': doDefault
};

(actions[key] || actions['default'])();

				
			
  • Các trường hợp sử dụng: Khi cần ánh xạ các khóa để thực hiện các hành động cụ thể, đặc biệt khi có nhiều hành động tiềm năng.

  • Hiệu suất: Việc tra cứu đối tượng thường nhanh hơn một câu lệnh switch, đặc biệt đối với một số lượng lớn trường hợp.

  • Khả năng tương thích: Hoạt động trong tất cả các phiên bản JavaScript hiện đại.

Chuyển đổi Mảng sang Boolean

Trong các tình huống mà bạn cần kiểm tra nếu một mảng là rỗng hay không, bạn có thể tận dụng việc ép kiểu của JavaScript.

				
					// Longhand
if (arr.length > 0) {
    // Array is not empty
}


// Shorthand
if (arr.length) {
    // Array is not empty
}

				
			
  • Các trường hợp sử dụng: Kiểm tra nhanh nếu một mảng (hoặc chuỗi) là rỗng.

  • Hiệu suất: Cả hai phương pháp đều hiệu quả, nhưng viết tắt cung cấp cú pháp gọn gàng hơn.

  • Khả năng tương thích: Được hỗ trợ toàn diện trong JavaScript.

Kỹ thuật viết tắt cho Vòng lặp

Vòng lặp `for...of` (cho Mảng)

Câu lệnh for...of tạo ra một vòng lặp lặp qua các đối tượng lặp lại, bao gồm: chuỗi cơ bản, Mảng, các đối tượng giống như mảng, TypedArray, Map, Set và các đối tượng lặp do người dùng định nghĩa.

				
					// Longhand
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
}


// Shorthand
for (const value of arr) {
    console.log(value);
}

				
			
  • Các trường hợp sử dụng: Khi bạn muốn lặp qua các giá trị của một đối tượng lặp, đặc biệt khi bạn không cần truy cập vào chỉ số.

  • Hiệu suất: Hiệu suất chung tương tự với các vòng lặp for truyền thống cho mảng.

  • Khả năng tương thích: Được hỗ trợ trong ES6 trở lên.

Vòng lặp `for...in` (cho Đối tượng)

Câu lệnh for...in lặp qua tất cả các thuộc tính có thể liệt kê của một đối tượng, theo một thứ tự tùy ý.

				
					// Longhand
for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
        console.log(key, obj[key]);
    }
}


// Shorthand
for (const key in obj) {
    console.log(key, obj[key]);
}

				
			
  • Các trường hợp sử dụng: Khi bạn muốn lặp qua các thuộc tính của một đối tượng.

  • Hiệu suất: Nó hiệu quả đối với đối tượng, nhưng không được khuyến nghị cho mảng.

  • Khả năng tương thích: Được hỗ trợ trong tất cả các phiên bản JavaScript.

Phương thức `forEach` của Mảng

Phương thức forEach() thực thi một hàm đã cung cấp một lần cho mỗi phần tử mảng.

				
					// Longhand
for (let i = 0; i < arr.length; i++) {
    doSomething(arr[i]);
}


// Shorthand
arr.forEach(item => doSomething(item));

				
			
  • Các trường hợp sử dụng: Khi bạn muốn một cách gọn gàng để lặp qua các phần tử mảng mà không cần đến chỉ số.

  • Hiệu suất: Chậm hơn một chút so với vòng lặp for truyền thống nhưng thường dễ đọc hơn.

  • Khả năng tương thích: Được hỗ trợ trong ES5 trở lên.

`map`, `filter`, và `reduce`

Đây là những phương thức mảng mạnh mẽ có thể thay thế cho các vòng lặp truyền thống, đặc biệt khi biến đổi mảng.

				
					// Using map to double each item
const doubled = arr.map(item => item * 2);

// Using filter to select even items
const evens = arr.filter(item => item % 2 === 0);

// Using reduce to sum all items
const sum = arr.reduce((acc, item) => acc + item, 0);

				
			
  • Các trường hợp sử dụng:

    • map: Khi biến đổi từng mục trong một mảng.
    • filter: Khi chọn một tập hợp con của các mục dựa trên tiêu chí nào đó.
    • reduce: Khi tích lũy một giá trị duy nhất từ một mảng.
  • Hiệu suất: Những phương thức này thường dễ đọc hơn so với vòng lặp truyền thống, nhưng có thể có một chút overhead về hiệu suất đối với mảng rất lớn.

  • Khả năng tương thích: Được hỗ trợ trong ES5 trở lên.

Phương thức `every` và `some` của Mảng

Những phương thức này được sử dụng để kiểm tra các phần tử mảng đối với một điều kiện.

				
					const numbers = [10, 20, 30, 40, 50];

// Check if all numbers are greater than 5
const allGreaterThanFive = numbers.every(num => num > 5); // true

// Check if any number is less than 25
const anyLessThanTwentyFive = numbers.some(num => num < 25); // false

				
			
  • Các trường hợp sử dụng:

    • every: Để kiểm tra xem tất cả các phần tử của một mảng có thỏa mãn một điều kiện không.
    • some: Để kiểm tra xem ít nhất một phần tử của một mảng có thỏa mãn một điều kiện không.
  • Hiệu suất: Hiệu quả hơn so với vòng lặp truyền thống cho những kiểm tra cụ thể này vì chúng dừng lại việc lặp một khi điều kiện được tìm thấy là sai (cho every) hoặc đúng (cho some).

  • Khả năng tương thích: Được hỗ trợ trong ES5 trở lên.

Phương thức `Array.from` kết hợp với `map`

Phương thức Array.from() tạo ra một phiên bản mới, được sao chép nông của một mảng. Khi kết hợp với một hàm map, nó có thể thay thế vòng lặp để tạo mảng dựa trên các cấu trúc dữ liệu khác hoặc khoảng.

				
					// Create an array of squares from 0 to 4
const squares = Array.from({ length: 5 }, (_, i) => i * i); // [0, 1, 4, 9, 16]

				
			
  • Các trường hợp sử dụng:

    • Chuyển đổi các cấu trúc giống mảng (như NodeList) thành mảng.
    • Tạo mảng từ các đối tượng lặp.
  • Hiệu suất: Hiệu quả và thường dễ đọc hơn khi chuyển đổi cấu trúc dữ liệu thành mảng.

  • Khả năng tương thích: Được hỗ trợ trong ES6 trở lên.

Sử dụng Toán tử Lan truyền để Chuyển đổi Cấu trúc giống Mảng

Toán tử lan truyền (...) có thể được sử dụng để chuyển đổi các cấu trúc giống mảng (ví dụ: NodeList, đối tượng arguments) thành mảng.

				
					// Converting NodeList to Array
const nodes = document.querySelectorAll('div');
const nodesArray = [...nodes];

// Converting arguments object to array
function logArgs() {
  const args = [...arguments];
  console.log(args);
}

				
			
  • Các trường hợp sử dụng:

    • Chuyển đổi bộ sưu tập nút DOM thành mảng.
    • Chuyển đổi đối tượng arguments thành một mảng bên trong các hàm.
  • Hiệu suất: Thường hiệu quả, đặc biệt cho các bộ sưu tập nhỏ hơn.

  • Khả năng tương thích: Toán tử lan truyền được hỗ trợ trong ES6 trở lên.

Vòng lặp `for...of` đệ quy cho Mảng Lồng nhau

Vòng lặp for...of của JavaScript có thể được sử dụng đệ quy để xử lý các mảng trong mảng, thường được gọi là “mảng lồng”.

				
					function recursiveForOf(arr) {
  for (const item of arr) {
    if (Array.isArray(item)) {
      recursiveForOf(item);
    } else {
      console.log(item);
    }
  }
}

const nestedArray = [1, [2, 3], [4, [5, 6]]];
recursiveForOf(nestedArray); // Logs 1, 2, 3, 4, 5, 6

				
			
  • Các trường hợp sử dụng:

    • Làm phẳng mảng lồng.
    • Lặp qua các cấu trúc dữ liệu đa cấp.
  • Hiệu suất: Đệ quy có thể tốn nhiều bộ nhớ đối với mảng lồng sâu. Luôn cẩn trọng với các lỗi tràn ngăn xếp tiềm năng.

  • Khả năng tương thích: for...of được hỗ trợ trong ES6 trở lên.

Phương thức `Array.reduce()` cho Biến đổi

Phương thức Array.reduce() áp dụng một hàm đối với một bộ tích lũy và từng phần tử trong mảng (từ trái sang phải) để giảm nó xuống một giá trị duy nhất.

				
					const numbers = [1, 2, 3, 4];
const sum = numbers.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
console.log(sum); // Outputs: 10

				
			
  • Các trường hợp sử dụng:

    • Tính tổng các giá trị mảng.
    • Biến đổi mảng thành các cấu trúc dữ liệu khác.
  • Hiệu suất: Rất hiệu quả khi biến đổi dữ liệu trong một lần duyệt.

  • Khả năng tương thích: Được hỗ trợ trong ES5 trở lên.

Phương thức `Array.flatMap()` để Ánh xạ và Làm phẳng

Array.flatMap() tương tự như Array.map(), nhưng nó trước tiên ánh xạ từng phần tử sử dụng một hàm ánh xạ, sau đó làm phẳng kết quả thành một mảng mới.

				
					const arr = [1, 2, 3, 4];
const result = arr.flatMap(x => [x, x * 2]);
console.log(result); // Outputs: [1, 2, 2, 4, 3, 6, 4, 8]

				
			
  • Các trường hợp sử dụng:

    • Khi bạn muốn ánh xạ và sau đó làm phẳng kết quả thành một mảng mới.
  • Hiệu suất: Hiệu quả cho các hoạt động ánh xạ và làm phẳng kết hợp.

  • Khả năng tương thích: Được hỗ trợ trong ES2019 trở lên.

Viết tắt của Hàm

Hàm Mũi tên

Hàm mũi tên cho phép cú pháp ngắn gọn hơn khi viết hàm trong JavaScript. Chúng đặc biệt hữu ích cho các hàm nhỏ với mục đích duy nhất.

				
					// Longhand
function add(x, y) {
  return x + y;
}


// Shorthand
const add = (x, y) => x + y;

				
			
  • Các trường hợp sử dụng:

    • Callbacks trong các hàm cấp cao hơn.
    • Bộ xử lý sự kiện.
    • Các hàm biểu thức đơn.
  • Hiệu suất: Hiệu suất tương tự như các hàm truyền thống.

  • Khả năng tương thích: Được hỗ trợ trong ES6 trở lên.

Tham số Mặc định

Tham số mặc định cho phép bạn đặt giá trị mặc định cho tham số hàm của mình. Điều này hữu ích khi một đối số không được cung cấp.

				
					// Longhand
function greet(name) {
  if(name === undefined) {
    name = "Guest";
  }
  return "Hello, " + name;
}


// Shorthand
const greet = (name = "Guest") => "Hello, " + name;

				
			
  • Các trường hợp sử dụng:

    • Đặt giá trị mặc định cho đối số hàm.
    • Tránh kiểm tra đối số không xác định hoặc bị thiếu.
  • Hiệu suất: Không có sự khác biệt đáng kể về hiệu suất.

  • Khả năng tương thích: Được hỗ trợ trong ES6 trở lên.

Trả về Ngầm định

Đối với các hàm mũi tên có một biểu thức đơn trong phần thân, bạn có thể bỏ qua từ khóa return và dấu ngoặc nhọn.

				
					// Longhand
const double = (x) => {
  return x * 2;
}


// Shorthand
const double = x => x * 2;

				
			
  • Các trường hợp sử dụng:

    • Các hàm tiện ích nhỏ.
    • Callbacks với một hoạt động duy nhất.
  • Hiệu suất: Không có sự khác biệt đáng kể về hiệu suất.

  • Khả năng tương thích: Được hỗ trợ trong ES6 trở lên.

Thuộc tính Tên của Hàm

Hàm trong JavaScript có một thuộc tính name trả về tên của hàm.

				
					function greet() {}
console.log(greet.name); // Outputs: "greet"


// For anonymous functions, the `name` property is an empty string:
let greet = function() {}
console.log(greet.name); // Outputs: ""


// However, when assigned to a variable, the variable `name` is adopted:
let greetFunc = function greet() {}
console.log(greetFunc.name); // Outputs: "greet"

				
			
  • Các trường hợp sử dụng:

    • Gỡ lỗi: Giúp xác định các hàm trong dấu vết ngăn xếp.
    • Phân tích hàm.
  • Hiệu suất: Chi phí phụ tối thiểu.

  • Khả năng tương thích: Được hỗ trợ trong ES6 trở lên.

Tham số Được Đặt tên với Destructuring

Sử dụng destructuring đối tượng để mô phỏng các tham số đã đặt tên trong hàm.

				
					// Longhand
function userInfo(user) {
  const name = user.name;
  const age = user.age;
  //...
}


// Shorthand
const userInfo = ({name, age}) => {
  //...
};

				
			
  • Các trường hợp sử dụng:

    • Khi các hàm có nhiều tham số, làm cho chúng khó quản lý.
    • Cải thiện tính rõ ràng của lời gọi hàm.
  • Hiệu suất: Chi phí phụ tối thiểu do việc destructuring.

  • Khả năng tương thích: Được hỗ trợ trong ES6 trở lên.

Share this
Send this to a friend