HomeLập trìnhJavaScriptCách sử dụng...

Cách sử dụng Bộ lọc, Bản đồ và Giảm để có mã dễ bảo trì hơn


của Guido Schmitz

Các hàm bậc cao hơn có thể giúp bạn đẩy mạnh trò chơi JavaScript của mình bằng cách làm cho mã của bạn có tính khai báo hơn. Đó là, ngắn gọn, đơn giản và dễ đọc.

Hàm bậc cao hơn là bất kỳ hàm nào trả về một hàm khi được thực thi, nhận một hàm làm một hoặc nhiều đối số của nó hoặc cả hai. Nếu bạn đã sử dụng bất kỳ Array phương pháp như map hoặc filterhoặc chuyển hàm gọi lại cho jQuery $.getbạn đã làm việc với Higher Order Functions.

Khi bạn sử dụng Array.mapbạn cung cấp một hàm làm đối số duy nhất của nó, hàm này áp dụng cho mọi phần tử có trong mảng.

var arr = [ 1, 2, 3 ];

var arrDoubled = arr.map(function(num) {
  return num * 2;
});

console.log(arrDoubled); // [ 2, 4, 6 ]

Các hàm bậc cao hơn cũng có thể trả về một hàm. Ví dụ: bạn có thể tạo một hàm gọi là multiplyBy nhận vào một số và trả về một hàm nhân một số khác mà bạn cung cấp với số đầu tiên được cung cấp. Bạn có thể sử dụng phương pháp này để tạo một multiplyByTwo chức năng để chuyển đến Array.map. Điều này sẽ cho bạn kết quả giống như bạn đã thấy ở trên.

function multiplyBy(num1) {
  return function(num2) {
    return num1 * num2;
  }
}

var multiplyByTwo = multiplyBy(2);

var arr = [ 1, 2, 3 ];

var arrDoubled = arr.map(multiplyByTwo);

console.log(arrDoubled); // [ 2, 4, 6 ]

Biết khi nào và làm thế nào để sử dụng các chức năng này là điều cần thiết. Chúng làm cho mã của bạn dễ hiểu và dễ bảo trì hơn. Nó cũng giúp dễ dàng kết hợp các chức năng với nhau. Đây được gọi là bố cục và tôi sẽ không đi vào chi tiết nhiều ở đây. Trong bài viết này, tôi sẽ đề cập đến ba hàm bậc cao được sử dụng nhiều nhất trong JavaScript. đó là .filter(), .map().reduce().

Lọc

Hãy tưởng tượng viết một đoạn mã chấp nhận danh sách những người mà bạn muốn lọc ra những người bằng hoặc trên 18 tuổi.

Đọc thêm  Cách phát hiện bảng màu ưa thích của người dùng trong JavaScript

Danh sách của chúng tôi trông giống như dưới đây:

const people = [ { name: ‘John Doe’, age: 16 }, { name: ‘Thomas Calls’, age: 19 }, { name: ‘Liam Smith’, age: 20 }, { name: ‘Jessy Pinkman’, age: 18 },];

Hãy xem một ví dụ về hàm đặt hàng đầu tiên chọn những người trên 18 tuổi. Tôi đang sử dụng hàm mũi tên là một phần của tiêu chuẩn ECMAScript hoặc gọi tắt là ES6. Nó chỉ là một cách ngắn gọn hơn để định nghĩa một hàm và cho phép bạn bỏ qua việc nhập hàm và trả về, cũng như một số dấu ngoặc đơn, dấu ngoặc nhọn và dấu chấm phẩy.

const peopleAbove18 = (collection) => {  const results = [];   for (let i = 0; i < collection.length; i++) {    const person = collection[i];     if (person.age >= 18) {      results.push(person);    }  }
  return results;};

Bây giờ nếu chúng ta muốn chọn tất cả những người trong độ tuổi từ 18 đến 20 thì sao? Chúng ta có thể tạo một chức năng khác.

const peopleBetween18And20 = (collection) => {  const results = [];   for (let i = 0; i < collection.length; i++) {    const person = collection[i];     if (person.age >= 18 && person.age <= 20) {      results.push(person);    }  }
  return results;};

Bạn có thể đã nhận ra rất nhiều mã lặp lại ở đây. Điều này có thể được trừu tượng hóa thành một giải pháp tổng quát hơn. Hai chức năng này có điểm chung. Cả hai đều lặp qua một danh sách và lọc nó theo một điều kiện nhất định.

“Hàm bậc cao hơn là một hàm nhận một hoặc nhiều hàm làm đối số.”– Cầu đóng cửa

Chúng tôi có thể cải thiện chức năng trước đây của mình bằng cách sử dụng cách tiếp cận mang tính khai báo hơn, .filter().

const peopleAbove18 = (collection) => {  return collection    .filter((person) => person.age >= 18);}

Đó là nó! Chúng tôi có thể giảm rất nhiều mã bổ sung bằng cách sử dụng chức năng bậc cao hơn này. Nó cũng làm cho mã của chúng tôi dễ đọc hơn. Chúng tôi không quan tâm mọi thứ đang được lọc như thế nào, chúng tôi chỉ muốn nó được lọc. Tôi sẽ đi vào kết hợp các chức năng sau trong bài viết này.

Đọc thêm  Khóa JavaScript trong đối tượng – Cách kiểm tra xem một đối tượng có Khóa trong JS không

Bản đồ

Hãy lấy cùng một danh sách những người và một loạt tên cho biết người đó có thích uống cà phê hay không.

const coffeeLovers = [‘John Doe’, ‘Liam Smith’, ‘Jessy Pinkman’];

Cách bắt buộc sẽ như sau:

const addCoffeeLoverValue = (collection) => {  const results = [];   for (let i = 0; i < collection.length; i++) {    const person = collection[i];
    if (coffeeLovers.includes(person.name)) {      person.coffeeLover = true;    } else {      person.coffeeLover = false;    }     results.push(person);  }   return results;};

chúng ta có thể sử dụng .map() để làm cho điều này tuyên bố nhiều hơn.

const incrementAge = (collection) => {  return collection.map((person) => {    person.coffeeLover = coffeeLovers.includes(person.name);     return person;  });};

Lần nữa, .map() là hàm bậc cao. Nó cho phép một hàm được truyền dưới dạng đối số.

Giảm

Tôi cá là bạn sẽ thích chức năng này khi bạn biết khi nào và làm thế nào để sử dụng nó.
Điều thú vị về .reduce() là hầu hết các chức năng trên có thể được thực hiện với nó.

Trước tiên hãy lấy một ví dụ đơn giản. Chúng tôi muốn tổng hợp tất cả các lứa tuổi của mọi người. Một lần nữa, chúng ta sẽ xem làm thế nào điều này có thể được thực hiện bằng cách sử dụng phương pháp mệnh lệnh. Về cơ bản, nó lặp qua bộ sưu tập và tăng một biến theo độ tuổi.

const sumAge = (collection) => {  let num = 0;   collection.forEach((person) => {    num += person.age;  });   return num;}

Và cách tiếp cận khai báo bằng cách sử dụng .reduce().

const sumAge = (collection) => collection.reduce((sum, person) => { return sum + person.age;}, 0);

Chúng ta thậm chí có thể sử dụng .reduce() để tạo ra triển khai của riêng chúng tôi về .map().filter() .

const map = (collection, fn) => {  return collection.reduce((acc, item) => {    return acc.concat(fn(item));  }, []);}
const filter = (collection, fn) => {  return collection.reduce((acc, item) => {    if (fn(item)) {      return acc.concat(item);    }     return acc;  }, []);}

Điều này có thể khó hiểu lúc đầu. Nhưng cái gì .reduce() về cơ bản là bắt đầu với một bộ sưu tập và một biến có giá trị ban đầu. Sau đó, bạn lặp lại bộ sưu tập và nối thêm (hoặc thêm) các giá trị vào biến.

Đọc thêm  Nâng trong JavaScript với let và const – và nó khác với var như thế nào

Kết hợp bản đồ, bộ lọc và giảm

Tuyệt vời, rằng các chức năng này tồn tại. Nhưng phần tốt là chúng tồn tại trên nguyên mẫu Array trong JavaScript. Điều này có nghĩa là các chức năng này có thể được sử dụng cùng nhau! Điều này giúp dễ dàng tạo các hàm có thể sử dụng lại và giảm số lượng mã cần thiết để viết một số chức năng nhất định.

Vì vậy, chúng tôi đã nói về việc sử dụng .filter() để lọc ra những người bằng hoặc dưới 18 tuổi. .map() để thêm coffeeLover tài sản, và .reduce() để cuối cùng tính tổng số tuổi của tất cả mọi người cộng lại.
Hãy viết một số mã thực sự kết hợp ba bước này.

const people = [ { name: ‘John Doe’, age: 16 }, { name: ‘Thomas Calls’, age: 19 }, { name: ‘Liam Smith’, age: 20 }, { name: ‘Jessy Pinkman’, age: 18 },];
const coffeeLovers = [‘John Doe’, ‘Liam Smith’, ‘Jessy Pinkman’];
const ageAbove18 = (person) => person.age >= 18;const addCoffeeLoverProperty = (person) => { person.coffeeLover = coffeeLovers.includes(person.name);  return person;}
const ageReducer = (sum, person) => { return sum + person.age;}, 0);
const coffeeLoversAbove18 = people .filter(ageAbove18) .map(addCoffeeLoverProperty);
const totalAgeOfCoffeeLoversAbove18 = coffeeLoversAbove18 .reduce(ageReducer);
const totalAge = people .reduce(ageReducer);

Nếu bạn làm theo cách bắt buộc, cuối cùng bạn sẽ viết rất nhiều mã lặp lại.

Tư duy tạo chức năng với .map() ,.reduce().filter() sẽ cải thiện chất lượng mã bạn sẽ viết. Nhưng nó cũng thêm rất nhiều khả năng đọc. Bạn không cần phải suy nghĩ về những gì đang diễn ra bên trong một chức năng. Thật dễ hiểu.

Cảm ơn vì đã đọc! 🙂

Nói xin chào Twitter





Zik.vn – Biên dịch & Biên soạn Lại

spot_img

Create a website from scratch

Just drag and drop elements in a page to get started with Newspaper Theme.

Buy Now ⟶

Bài viết liên quang

DMCA.com Protection Status