Hướng dẫn Underscore.js: Cách sử dụng thư viện JavaScript mạnh mẽ cho xử lý mảng và đối tượng

目次

1. Giới thiệu

JavaScript là một ngôn ngữ lập trình không thể thiếu trong phát triển Web, tuy nhiên việc thao tác với mảng và đối tượng thường khiến mã trở nên phức tạp. Đặc biệt, trong các xử lý như lọc dữ liệu hay chuyển đổi dữ liệu, việc viết code ngắn gọn và hiệu quả là điều rất cần thiết. Đây chính là lúc thư viện Underscore.js trở nên hữu ích. Với thư viện này, bạn có thể viết ngắn gọn và dễ quản lý hơn khi thao tác với dữ liệu phức tạp.

Điểm nổi bật của Underscore.js

  1. Làm mã ngắn gọn hơn
  • Những đoạn xử lý dài dòng trong JavaScript truyền thống có thể được rút gọn chỉ trong vài dòng với Underscore.js.
  1. Nhiều hàm tiện ích có sẵn
  • Hỗ trợ xử lý mảng, đối tượng, điều khiển hàm và nhiều chức năng khác.
  1. Nhẹ và linh hoạt
  • Có thể sử dụng trực tiếp các hàm cần thiết, hạn chế tối đa ảnh hưởng đến hiệu suất.

Những gì bạn sẽ học trong bài viết này

  • Cách cài đặt Underscore.js
  • Các hàm cơ bản và ví dụ áp dụng
  • Những tình huống thực tế trong phát triển

2. Underscore.js là gì

Tổng quan về Underscore.js

Underscore.js là một thư viện nhẹ giúp thao tác dữ liệu trong JavaScript dễ dàng hơn. Nó cung cấp rất nhiều hàm tiện ích cho xử lý mảng và đối tượng, được xem như một bộ công cụ hỗ trợ JavaScript. JavaScript mặc định đã mạnh mẽ, nhưng đôi khi mã quá dài hoặc khó đọc. Với Underscore.js, bạn có thể viết code đơn giản, rõ ràng và dễ bảo trì hơn.

Đặc điểm chính

  1. Đa dạng hàm tiện ích
  • Cung cấp nhiều hàm như xử lý mảng, xử lý đối tượng, kiểm soát hàm
  1. Mã ngắn gọn, dễ đọc
  • Ít dòng hơn so với JavaScript thuần, giúp code rõ ràng hơn.
  1. Không phụ thuộc
  • Không phụ thuộc vào thư viện khác, dễ dàng tích hợp.
  1. Nhẹ và nhanh
  • Kích thước nhỏ, hiệu suất tốt, phù hợp cho các ứng dụng Web hiện đại.

So sánh Underscore.js và Lodash

Thư viện thường được so sánh với Underscore.js là Lodash. Lodash phát triển dựa trên Underscore.js và bổ sung nhiều tính năng.
Đặc điểmUnderscore.jsLodash
Tính năngNhiều hàm tiện ích cơ bảnBổ sung và mở rộng thêm nhiều hàm
Hỗ trợ moduleMột phầnHỗ trợ đầy đủ
Hiệu suấtNhanhNhanh hơn, tối ưu hơn
Việc lựa chọn phụ thuộc vào yêu cầu dự án, nhưng nếu bạn cần một thư viện đơn giản và nhẹ, Underscore.js là lựa chọn phù hợp.

3. Cách cài đặt

Trong phần này, chúng ta sẽ tìm hiểu cách thêm Underscore.js vào dự án. Có 2 cách phổ biến: dùng CDN và tải file trực tiếp, ngoài ra bạn cũng có thể cài đặt bằng npm hoặc yarn.

1. Sử dụng CDN

CDN (Content Delivery Network) cho phép sử dụng thư viện chỉ bằng cách thêm đường dẫn vào HTML. Thêm đoạn mã sau vào trong thẻ <head> hoặc cuối <body>:

Ví dụ: Thêm vào HTML

<!DOCTYPE html>
<html lang="vi">
<head>
  <meta charset="UTF-8">
  <title>Cài đặt Underscore.js</title>
  <!-- Liên kết CDN của Underscore.js -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.6/underscore-min.js"></script>
</head>
<body>
  <h1>Kiểm tra Underscore.js</h1>
  <script>
    // Kiểm tra hoạt động
    const data = [1, 2, 3, 4, 5];
    const evenNumbers = _.filter(data, function(num) {
      return num % 2 === 0;
    });
    console.log(evenNumbers); // [2, 4]
  </script>
</body>
</html>
Khi mở bằng trình duyệt, bạn sẽ thấy chỉ số chẵn hiển thị trong console.

2. Cài đặt với npm hoặc yarn

Nếu bạn làm việc với Node.js hoặc môi trường hiện đại, có thể cài bằng npm hoặc yarn.

Cài bằng npm

npm install underscore

Cài bằng yarn

yarn add underscore

Ví dụ import trong JavaScript

import _ from 'underscore';

const data = [10, 20, 30, 40];
const result = _.map(data, (num) => num * 2);
console.log(result); // [20, 40, 60, 80]

3. Tải file trực tiếp

  1. Truy cập trang chính thức.
  2. Tải file JavaScript trong phần “Download”.
  3. Đặt file vào thư mục (ví dụ: js/).
  4. Thêm vào HTML bằng thẻ script.
<script src="js/underscore-min.js"></script>

4. Sử dụng với module bundler

Khi dùng Webpack hay Parcel, bạn có thể tích hợp rất dễ.

Ví dụ với Webpack

  1. Cài đặt bằng npm.
npm install underscore
  1. Import trong file JavaScript.
import _ from 'underscore';
  1. Bundle và sử dụng trong dự án.

Xử lý sự cố

1. Báo lỗi “Uncaught ReferenceError: _ is not defined”
  • Kiểm tra lại đường dẫn CDN hoặc import.
2. Lỗi khi cài bằng npm
  • Đảm bảo Node.js và npm được cập nhật bản mới nhất.

4. Cách sử dụng cơ bản

Trong phần này, chúng ta sẽ tìm hiểu các hàm cơ bản của Underscore.js và ví dụ minh họa. Những hàm này rất hữu ích để thao tác mảng và đối tượng một cách hiệu quả.

1. Lặp qua mảng – _.each()

_.each() được dùng để lặp qua từng phần tử trong mảng hoặc đối tượng.

Ví dụ

const numbers = [1, 2, 3, 4, 5];

// In ra từng phần tử
_.each(numbers, function(num) {
  console.log(num);
});
Kết quả:
1
2
3
4
5
Lưu ý:
  • Có thể dùng cho cả đối tượng.
  • Callback nhận (giá trị, chỉ số, toàn bộ mảng).

2. Tạo mảng mới – _.map()

_.map() áp dụng một hàm cho từng phần tử và trả về mảng mới.

Ví dụ

const numbers = [1, 2, 3, 4, 5];

// Nhân đôi từng phần tử
const doubled = _.map(numbers, function(num) {
  return num * 2;
});

console.log(doubled);
Kết quả:
[2, 4, 6, 8, 10]

3. Tìm phần tử đầu tiên phù hợp – _.find()

_.find() trả về phần tử đầu tiên thỏa mãn điều kiện.

Ví dụ

const numbers = [1, 2, 3, 4, 5];

// Tìm số đầu tiên >= 3
const result = _.find(numbers, function(num) {
  return num >= 3;
});

console.log(result);
Kết quả:
3

4. Lọc nhiều phần tử – _.filter()

_.filter() trả về tất cả phần tử thỏa mãn điều kiện.

Ví dụ

const numbers = [1, 2, 3, 4, 5];

// Lấy các số chẵn
const evens = _.filter(numbers, function(num) {
  return num % 2 === 0;
});

console.log(evens);
Kết quả:
[2, 4]

5. Xáo trộn mảng – _.shuffle()

_.shuffle() sắp xếp lại mảng theo thứ tự ngẫu nhiên.

Ví dụ

const numbers = [1, 2, 3, 4, 5];

const shuffled = _.shuffle(numbers);
console.log(shuffled);
Kết quả (ví dụ):
[3, 5, 1, 4, 2]

6. Loại bỏ trùng lặp – _.uniq()

_.uniq() xóa các phần tử trùng lặp trong mảng.

Ví dụ

const numbers = [1, 2, 2, 3, 4, 4, 5];

const uniqueNumbers = _.uniq(numbers);
console.log(uniqueNumbers);
Kết quả:
[1, 2, 3, 4, 5]

Tóm tắt

Trong phần này, chúng ta đã học các hàm cơ bản của Underscore.js:
  • _.each() – lặp qua phần tử
  • _.map() – tạo mảng mới
  • _.find()_.filter() – tìm và lọc dữ liệu
  • _.shuffle() – xáo trộn ngẫu nhiên
  • _.uniq() – loại bỏ trùng lặp

5. Cách sử dụng nâng cao

Trong phần này, chúng ta sẽ khám phá các hàm nâng cao trong Underscore.js, giúp thao tác và phân tích dữ liệu phức tạp hơn.

1. Sắp xếp mảng – _.sortBy()

_.sortBy() dùng để sắp xếp mảng theo khóa hoặc điều kiện.

Ví dụ

const users = [
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 20 },
  { name: 'Charlie', age: 30 }
];

const sortedUsers = _.sortBy(users, 'age');
console.log(sortedUsers);
Kết quả:
[
  { name: 'Bob', age: 20 },
  { name: 'Alice', age: 25 },
  { name: 'Charlie', age: 30 }
]

2. Nhóm phần tử – _.groupBy()

_.groupBy() chia mảng thành các nhóm dựa trên điều kiện hoặc khóa.

Ví dụ

const numbers = [1.1, 2.3, 2.4, 3.5, 4.7];

const grouped = _.groupBy(numbers, function(num) {
  return Math.floor(num);
});

console.log(grouped);
Kết quả:
{
  1: [1.1],
  2: [2.3, 2.4],
  3: [3.5],
  4: [4.7]
}

3. Thống kê dữ liệu – _.countBy()

_.countBy() đếm số lượng phần tử theo một điều kiện nhất định.

Ví dụ

const words = ['apple', 'banana', 'apricot', 'blueberry'];

const counts = _.countBy(words, function(word) {
  return word[0];
});

console.log(counts);
Kết quả:
{
  a: 2,
  b: 2
}

Tóm tắt

Các hàm nâng cao đã học:
  • _.sortBy() – sắp xếp mảng
  • _.groupBy()_.countBy() – nhóm và thống kê dữ liệu

6. Thao tác với đối tượng

Trong phần này, chúng ta sẽ tìm hiểu các hàm của Underscore.js giúp xử lý đối tượng một cách hiệu quả. Những hàm này hỗ trợ lấy khóa, giá trị và tạo bản sao đối tượng.

1. Lấy khóa và giá trị của đối tượng

Lấy khóa – _.keys()

const person = { name: 'Alice', age: 25, city: 'Tokyo' };

const keys = _.keys(person);
console.log(keys);
Kết quả:
['name', 'age', 'city']

Lấy giá trị – _.values()

const values = _.values(person);
console.log(values);
Kết quả:
['Alice', 25, 'Tokyo']

2. Tạo bản sao đối tượng – _.clone()

_.clone() tạo một bản sao nông (shallow copy) của đối tượng.
const original = { name: 'Alice', age: 25 };
const clone = _.clone(original);

clone.age = 30; // thay đổi bản sao
console.log(original.age); // 25
console.log(clone.age);    // 30

Tóm tắt

Trong phần này, bạn đã học cách thao tác đối tượng với Underscore.js:
  • _.keys() – lấy danh sách khóa
  • _.values() – lấy danh sách giá trị
  • _.clone() – tạo bản sao đối tượng

7. Thao tác với hàm

Trong phần này, chúng ta sẽ tìm hiểu cách sử dụng Underscore.js để kiểm soát việc thực thi hàm, giúp tối ưu hiệu suất và quản lý luồng xử lý tốt hơn.

1. Ràng buộc ngữ cảnh – _.bind()

_.bind() cho phép cố định this khi thực thi một hàm.

Ví dụ

const person = {
  name: 'Alice',
  greet: function(greeting) {
    return `${greeting}, my name is ${this.name}`;
  }
};

const boundGreet = _.bind(person.greet, person);
console.log(boundGreet('Hello')); // Hello, my name is Alice

2. Trì hoãn thực thi – _.delay()

_.delay() cho phép trì hoãn thực thi hàm theo thời gian nhất định.

Ví dụ

_.delay(function(message) {
  console.log(message);
}, 2000, 'Xuất hiện sau 2 giây');
Kết quả (sau 2 giây):
Xuất hiện sau 2 giây

3. Chỉ thực thi một lần – _.once()

_.once() đảm bảo hàm chỉ được gọi một lần duy nhất.

Ví dụ

const initialize = _.once(function() {
  console.log('Khởi tạo hoàn tất');
});

initialize(); // chạy
initialize(); // bị bỏ qua

4. Ghi nhớ kết quả – _.memoize()

_.memoize() lưu trữ kết quả của hàm, giúp bỏ qua tính toán lặp lại với cùng tham số.

Ví dụ

const factorial = _.memoize(function(n) {
  return n <= 1 ? 1 : n * factorial(n - 1);
});

console.log(factorial(5)); // tính toán
console.log(factorial(5)); // dùng cache

5. Giới hạn tần suất – _.throttle()

_.throttle() kiểm soát số lần hàm được thực thi trong một khoảng thời gian.

Ví dụ

const log = _.throttle(function() {
  console.log('Đang xử lý...');
}, 2000);

// mô phỏng nhiều sự kiện click liên tục
setInterval(log, 500); // chỉ chạy 2s một lần

Tóm tắt

Các hàm thao tác với function trong Underscore.js:
  • _.bind() – cố định ngữ cảnh this
  • _.delay() – trì hoãn thực thi
  • _.once() – chỉ chạy một lần
  • _.memoize() – lưu cache kết quả
  • _.throttle() – giới hạn tần suất gọi hàm

8. Các hàm tiện ích

Underscore.js cung cấp nhiều hàm tiện ích giúp xử lý dữ liệu, tạo số ngẫu nhiên hoặc sử dụng như một công cụ template đơn giản.

1. Sinh số ngẫu nhiên – _.random()

_.random() tạo số nguyên hoặc số thực ngẫu nhiên trong khoảng chỉ định.

Ví dụ

console.log(_.random(1, 10)); // số nguyên từ 1 đến 10
console.log(_.random(1, 10, true)); // số thực từ 1 đến 10

2. Kiểm tra giá trị rỗng – _.isEmpty()

_.isEmpty() kiểm tra xem mảng, đối tượng hoặc chuỗi có rỗng không.

Ví dụ

console.log(_.isEmpty([]));      // true
console.log(_.isEmpty({}));      // true
console.log(_.isEmpty(''));      // true
console.log(_.isEmpty([1,2,3])); // false

3. Tạo template – _.template()

_.template() giúp tạo template chuỗi động.

Ví dụ

const template = _.template('Xin chào, <%= name %>!');
console.log(template({ name: 'Alice' }));
Kết quả:
Xin chào, Alice!

Tóm tắt

Các hàm tiện ích phổ biến:
  • _.random() – sinh số ngẫu nhiên
  • _.isEmpty() – kiểm tra dữ liệu rỗng
  • _.template() – tạo template chuỗi

9. Kết luận

Trong bài viết này, chúng ta đã tìm hiểu từ cơ bản đến nâng cao về cách sử dụng Underscore.js. Thư viện này giúp đơn giản hóa việc thao tác dữ liệu trong JavaScript và viết code hiệu quả hơn.

Tóm tắt nội dung

  1. Cách sử dụng cơ bản – học các hàm thao tác mảng và đối tượng.
  2. Cách sử dụng nâng cao – sắp xếp, phân nhóm và thống kê dữ liệu.
  3. Thao tác với hàm – kiểm soát việc thực thi, cache và tối ưu hiệu suất.
  4. Hàm tiện ích – sinh số ngẫu nhiên, kiểm tra dữ liệu rỗng, sử dụng template.

Kết lời

Underscore.js là một công cụ mạnh mẽ giúp phát triển JavaScript dễ dàng và hiệu quả hơn. Hãy áp dụng trong dự án của bạn để tăng tốc độ phát triển và nâng cao kỹ năng lập trình.

Câu hỏi thường gặp (FAQ)

Q1: Underscore.js có miễn phí không?

A: Có, thư viện được cung cấp theo giấy phép MIT và có thể dùng miễn phí kể cả trong dự án thương mại.

Q2: Khác biệt giữa Underscore.js và Lodash là gì?

A: Underscore.js nhẹ và đơn giản, trong khi Lodash được phát triển dựa trên Underscore với nhiều tính năng hơn, tối ưu hiệu suất và hỗ trợ module đầy đủ. Tùy nhu cầu dự án để chọn.

Q3: Với JavaScript ES6+ thì có cần Underscore.js không?

A: Nhiều tính năng đã có sẵn trong ES6+, nhưng Underscore.js vẫn hữu ích khi cần viết ngắn gọn, dễ đọc, hoặc khi xử lý tương thích với trình duyệt cũ.

Q4: Phù hợp với loại dự án nào?

A: Thích hợp cho dự án nhỏ đến trung bình, hoặc khi bạn muốn viết code ngắn gọn và hiệu quả mà không cần thư viện nặng nề.

Q5: Cách cài đặt Underscore.js?

A: Có thể dùng nhiều cách:
  1. CDN:
    <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.13.6/underscore-min.js"></script>
  2. npm:
    npm install underscore
  3. yarn:
    yarn add underscore

Q6: Tài liệu chính thức ở đâu?

A: Có thể xem tại trang chính thức của Underscore.js.

Q7: Có dùng được cho dự án lớn không?

A: Có, nhưng với dự án lớn Lodash thường được khuyến nghị hơn vì hỗ trợ tối ưu hóa tốt hơn. Tuy nhiên Underscore.js vẫn hữu ích cho các dự án nhẹ.

Q8: Có cách khác để kiểm soát hàm không?

A: Có, JavaScript hiện đại hỗ trợ setTimeout(), setInterval(), Promise, async/await. Tuy nhiên, dùng _.throttle() hay _.debounce() sẽ ngắn gọn và tiện lợi hơn.

Q9: Cần lưu ý gì khi dùng?

A:
  1. Không nên phụ thuộc quá nhiều vì ES6+ đã có nhiều tính năng thay thế.
  2. Luôn dùng phiên bản mới nhất để tránh rủi ro bảo mật.
  3. Cân nhắc Lodash nếu dự án cần nhiều tính năng nâng cao.

Q10: Có nên dùng như template engine không?

A: _.template() hữu ích cho template đơn giản, nhưng nếu cần tính năng mạnh hơn, hãy cân nhắc các thư viện như Handlebars.js hoặc EJS.
広告