Lập trình chức năng trong ví dụ javascript là gì?

Từ bài viết này, bạn sẽ học cách viết mã chức năng trong JavaScript. Chúng ta sẽ tận dụng sức mạnh của các hàm JavaScript và tìm hiểu xem việc thực hiện các tác vụ phức tạp bằng lập trình hàm dễ dàng như thế nào. Ở cuối bài viết, bạn sẽ có thể sử dụng các khía cạnh chức năng của JavaScript, triển khai ghi nhớ và vận hành chức năng trên dữ liệu của mình. Chúng tôi sẽ tập trung vào một số ví dụ thực tế sẽ giúp bạn và đồng nghiệp của bạn tìm cách viết mã tốt hơn

Lập trình hàm là một mô hình khuyến khích các nhà phát triển viết mã không có dữ liệu có thể thay đổi và không trạng thái. Theo định nghĩa, nó yêu cầu chúng ta coi các chương trình của mình là các hàm toán học luôn tạo ra các kết quả giống hệt nhau khi các giá trị giống nhau được truyền vào chúng. Bởi vì chúng ta biết đầu ra của hàm sẽ như thế nào, cách tiếp cận này làm giảm số lượng bất ngờ trong mã

Mục lục

Lập trình khai báo so với lập trình mệnh lệnh

Trong thực tế, có thể bạn sẽ cần sử dụng kết hợp cả hai. Lập trình chức năng là khai báo. Điều đó có nghĩa là chúng ta khai báo nhiệm vụ hành động cần thực hiện mà không chỉ định các bước chính xác để đạt được điều đó. Nghe có vẻ giống như một phép thuật, phải không? . Giả sử chúng ta có danh sách 100 người giàu nhất thế giới và muốn có được tổng tài sản của mười người đứng đầu danh sách. Trong lập trình mệnh lệnh, có lẽ chúng ta sẽ làm điều gì đó như thế

const getTotalFortuneOfTenRichest = (người giàu) => {

người giàu. loại(

(thứ nhất, thứ hai) => thứ nhất. tiền - thứ hai. tiền bạc

);

để tổng = 0;

for (hãy i = 0; i < người giàu. chiều dài;

tổng += người giàu[i]. tiền bạc;

nếu (tôi >= 10) {

trả lại tổng;

}

}

};

Chức năng này hoàn thành vai trò của nó, nhưng chúng ta có thể làm tốt hơn bằng cách sử dụng lập trình khai báo như một phần trừu tượng cho mã của chúng ta. Theo cách viết mã bắt buộc, chúng tôi sử dụng các hướng dẫn cụ thể để sửa đổi cấu trúc, trong khi trong lập trình chức năng, chúng tôi chỉ định kết quả chúng tôi mong đợi là gì

  • chức năng sắp xếp thay đổi mảng. Khá bất ngờ khi truyền một biến vào hàm, sau khi thực hiện xong mới nhận thấy các biến có giá trị khác nhau
  • biến tổng có thể thay đổi. Nó thay đổi với mỗi lần lặp lại vòng lặp. Bây giờ nó không còn có hại nữa vì nó chỉ được sử dụng trong chức năng này và nó không rời khỏi nó. Nhưng thói quen tạo các biến có thể thay đổi có thể gây ra vấn đề khi chúng ta quen với nó và bắt đầu chuyển các biến có thể thay đổi qua ứng dụng của mình
  • Một điều khác bị loại bỏ khi tuân theo các hướng dẫn của lập trình chức năng là khai báo luồng thực thi. Chúng tôi chỉ định những gì nên được thực hiện trong mỗi bước
  • Trên hết, có những điều kiện có thể dừng lặp lại vòng lặp và quay trở lại từ chức năng. Những điều nhỏ nhặt như vậy làm cho mã khó đọc và khó hiểu hơn, vì việc thực thi mã theo dõi liên quan đến các biến khác nhau và các điều kiện đánh giá để theo dõi luồng

Làm cho mã hoạt động trong hầu hết các trường hợp có nghĩa là làm cho mã ít phức tạp hơn và dễ đọc hơn. Nó cũng cho phép chúng tôi tuân theo các quy tắc khác để viết mã tốt
Hãy xem ví dụ tương tự, nhưng được triển khai theo hướng dẫn của phong cách chức năng

const getTotalFortuneOfTenRichest = (người giàu) => (

[. người giàu]

sắp xếp ((thứ nhất, thứ hai) => thứ nhất. tiền - thứ hai. tiền bạc)

lát (0, 10)

giảm((tổng, người) => tổng + người. tiền, 0)

);

Nó rõ ràng là dễ đọc hơn so với ví dụ trước. Các hàm khai báo này hầu hết có thể sử dụng mã mệnh lệnh, nhưng với các khía cạnh chức năng của JavaScript, chúng ta không phải bận tâm đến cú pháp cấp thấp để hoạt động trên các cấu trúc

Bởi vì chúng tôi đã xác định các bước cần thực hiện, toàn bộ chức năng là bắt buộc, nhưng bao gồm các khối khai báo. Chúng tôi chỉ cần chỉ định kết quả nào chúng tôi mong đợi sau mỗi thao tác. Đầu tiên, mảng richPeople hiện được sao chép cạn bằng cách sử dụng toán tử trải rộng mảng để tránh sửa đổi biến đầu vào. Sau đó, mỗi bước được mô tả khai báo bằng cách sử dụng các khía cạnh chức năng của JavaScript. Chúng tôi muốn mảng được sắp xếp giảm dần theo mức độ giàu có của mọi người. Tiếp theo, chúng tôi chỉ muốn 10 người đầu tiên. Cuối cùng, bước cuối cùng là giảm toàn bộ mảng thành một giá trị duy nhất, được tính bằng cách cộng số tiền của mỗi người vào tổng, bắt đầu từ tổng bằng 0

chức năng thuần túy

Một khái niệm quan trọng khác mà bạn có thể muốn biết là độ tinh khiết của hàm. Định nghĩa tốt nhất nảy ra trong đầu tôi là. nếu chức năng có thể được biểu thị dưới dạng một cặp đối số và đầu ra của nó, thì nó được coi là thuần túy. Các hàm thuần túy luôn trả về cùng một kết quả và chỉ phụ thuộc vào các đối số được truyền cho chúng

Trong thực tế, các hàm thuần túy thực sự quan trọng để xây dựng ứng dụng – chúng ta có thể sử dụng chúng và kết hợp với bất kỳ hàm nào khác mà không phải lo lắng về kết quả ảnh hưởng đến trạng thái chung của ứng dụng. Các hàm thuần túy mang lại sự tự tin rằng không có tác dụng phụ nào sẽ sửa đổi một số biến nằm ngoài phạm vi của chúng

Hãy xem một ví dụ để minh họa nó. Hàm trước tính tổng lộc có thể coi là thuần. Tại sao?

Không có vấn đề gì, việc truyền cùng một mảng cho hàm sẽ dẫn đến cùng một kết quả. Nhưng mọi thứ không phải lúc nào cũng như vậy. Một số chức năng chúng tôi viết có vẻ thuần túy, nhưng chúng không. Xem xét ví dụ sau

const getFileContent = (tên tệp) =>

fs. readFileSync(tên tệp, 'utf8');

Là nó chức năng tinh khiết? . Thoạt nhìn, nó trả về nội dung tệp. Truyền cùng một tên tệp sẽ luôn trả về cùng một đầu ra, phải không? . Điều đó có nghĩa là ngay cả khi được cung cấp cùng một tên tệp, hàm có thể trả về nội dung khác nhau mỗi khi nó được gọi hoặc đưa ra một ngoại lệ nếu không tìm thấy tệp

Một hàm thuần túy cũng phải đảm bảo rằng nó không làm thay đổi dữ liệu và chỉ hoạt động trong phạm vi của chính nó. Hàm trong ví dụ đầu tiên là một ví dụ hoàn hảo về hàm có tác dụng phụ. Trong trường hợp này, nó chỉ thay đổi thứ tự của các phần tử trong một tham số mảng, nhưng nếu việc triển khai loại bỏ các phần tử không mong muốn khỏi mảng thì sao?

JavaScript và lập trình chức năng

JavaScript khuyến khích và cung cấp khả năng viết mã chức năng. Ngay bây giờ, chúng ta sẽ xem xét các chức năng cho phép chúng ta viết các ứng dụng tốt hơn

Lập trình chức năng trong ví dụ javascript là gì?

biến const

Kể từ ECMAScript2015, bạn có thể sử dụng const và let để khai báo các biến của mình. Sử dụng const khi khai báo biến của bạn, bạn có thể ngăn chúng gán lại. Ví dụ: khai báo sum là const sum sẽ đưa ra TypeError cho chúng tôi biết rằng chúng tôi đang cố gắng gán giá trị cho một biến không đổi. Khi bạn đã quen với việc viết các hàm thuần túy, bạn sẽ nhận thấy rằng không cần sử dụng các khai báo let hoặc var. Thay vào đó, hãy sử dụng các biến không đổi ở mọi nơi làm tiêu chuẩn để khai báo các biến của bạn

Tránh sử dụng các vòng lặp

JavaScript cung cấp các cách để loại bỏ các vòng lặp. Khai báo luồng của ứng dụng bằng cách sử dụng các vòng lặp có nghĩa là bắt buộc phải viết mã. Nếu chúng ta muốn viết mã chức năng, chúng ta có thể sử dụng

Bản đồ

Hàm bản đồ rất hữu ích để chuyển đổi các phần tử của mảng của chúng ta thành hình dạng mong muốn. Rất có thể, nếu bạn đã từng lưu trữ dữ liệu mọi người trong cơ sở dữ liệu, bạn đã lưu ngày sinh của họ thay vì tuổi của họ. Nếu bạn muốn hiển thị tuổi của họ, bạn có thể sử dụng chức năng bản đồ để làm như vậy

const convertBirthdateToAge = ({ ngày sinh,. người }) => (

{. người, tuổi tác. getAgeFromBirthdate(ngày sinh) }

);

mọi người. bản đồ (convertBirthdateToAge);

Điều này thực thi chức năng được cung cấp cho mọi phần tử trong mảng của chúng tôi và trả về một mảng mới. Mảng mới sẽ chứa các kết quả đầu ra của hàm convertBirthdateToAge được áp dụng cho các phần tử trong mảng người. Hàm Bản đồ nhận một hàm gọi lại được áp dụng cho mọi phần tử trong một mảng và kết quả là hàm gọi lại đó được thêm vào mảng kết quả. Hàm gọi lại lấy phần tử hiện đang được xử lý làm đối số đầu tiên và chỉ mục của phần tử đó làm đối số thứ hai. Ví dụ, đối số chỉ mục của hàm gọi lại có thể được sử dụng để thêm một số định danh vào mảng kết quả

const addId = (phần tử, chỉ số) => ({. phần tử, id. mục lục });

mọi người

bản đồ (convertToAge)

bản đồ (addId);

Chức năng bản đồ cũng hữu ích để thực hiện nhiều hoạt động không đồng bộ cùng một lúc mà không cần chờ kết quả mỗi lần. Hãy gắn bó với mảng con người của chúng tôi. Chúng tôi muốn lưu chúng vào cơ sở dữ liệu. Rất có thể, các hoạt động cơ sở dữ liệu được thực thi không đồng bộ và ý tưởng đầu tiên có thể xuất hiện trong đầu chúng ta là

for (const người của người) {

đang đợi saveToDatabase(person)

}

Vấn đề là chúng tôi đang đợi mỗi thao tác lưu hoàn tất trong mỗi lần lặp vòng lặp. Chúng ta có thể giải quyết vấn đề đó bằng chức năng bản đồ

const peopleSavers = người. bản đồ (saveToDatabase)

chờ đợi lời hứa. tất cả(ngườiSavers)

Trong ví dụ này, chúng tôi đang ánh xạ từng người tới kết quả chức năng không đồng bộ, đây là một lời hứa. Sau đó, chúng tôi đang chờ đợi tất cả các lời hứa hoàn thành

Lọc

Hàm Filter rất hữu ích để lọc một mảng theo cách khai báo. Chữ ký của chức năng bộ lọc gần giống như chức năng bản đồ. Sự khác biệt duy nhất là nó nhận một cuộc gọi lại có đầu ra cho biết liệu giá trị có nên được đưa vào mảng kết quả hay không. Nếu giá trị trả về của hàm gọi lại là giá trị sai, phần tử hiện đang được xử lý sẽ không có trong mảng đầu ra. Kết quả là, chúng ta nhận được một mảng các giá trị đáp ứng điều kiện được kiểm tra bởi hàm gọi lại
Vì đầu ra của cả chức năng bản đồ và chức năng bộ lọc là mảng, chúng tôi có thể xâu chuỗi các cuộc gọi và lọc mảng người của chúng tôi từ ví dụ trước để chỉ chứa những người từ 30 tuổi trở lên

const isOlderThan30 = ({ tuổi }) => tuổi >= 30;

mọi người

bản đồ (convertToAge)

bộ lọc (isOlderThan30);

Giảm bớt

Giảm là một chức năng khác thoạt nhìn có vẻ phức tạp nhưng nó thực sự hữu ích để viết mã chức năng. Giảm hoạt động trên mảng và thực hiện chức năng gọi lại cho từng phần tử tích lũy giá trị. Cuối cùng, kết quả là các giá trị tích lũy được trả về. Hãy nhảy vào một ví dụ để xem việc sử dụng thực tế của nó. Chúng tôi có một loạt các giờ làm việc giống như thế này

const số giờ làm việc = [

{ngày. "THỨ HAI", Thời gian bắt đầu. 10, thời gian kết thúc. 15},

{ngày. "THỨ BA", Thời gian bắt đầu. 10, thời gian kết thúc. 12},

{ngày. "THỨ SÁU", Thời gian bắt đầu. 15, thời gian kết thúc. 21},

]

Để chuyển đổi mảng thành một đối tượng chứa ngày làm khóa, chúng ta có thể sử dụng hàm rút gọn. Trong reduce, tham số đầu tiên là hàm gọi lại và tham số thứ hai là giá trị ban đầu. Tham số đầu tiên của hàm gọi lại là bộ tích lũy – một giá trị được trả về từ hàm gọi lại trên phần tử trước đó. Tham số thứ hai là phần tử hiện đang được xử lý

giờ làm việc. giảm bớt((

(trướcGiá trị, {ngày,. giờ}) => ({

giá trị trước đây,

[ngày]. giờ

})

), {})

Đầu ra sẽ trông như thế

{

THỨ HAI. { thời gian bắt đầu. 10, thời gian kết thúc. 15 },

THỨ BA. { thời gian bắt đầu. 10, thời gian kết thúc. 12 },

THỨ SÁU. { thời gian bắt đầu. 15, thời gian kết thúc. 21 }

}

Currying trong chức năng

Currying là một phần quan trọng của lập trình chức năng. Nó cho phép gọi các hàm mà không cần chỉ định tất cả các tham số cần thiết. Điều này có nghĩa là bạn sẽ không nhận được kết quả, nhưng một chức năng khác cho phép chúng tôi chuyển các tham số còn thiếu. Kết quả của hàm được trả về khi tất cả các đối số được truyền. Currying là điều cần thiết để xây dựng các chức năng có thể tái sử dụng. Ví dụ, chúng ta có thể thực hiện nó theo cách này

const getContentTemplate = nội dung => (

người dùng => (

`Xin chào ${người dùng}

${nội dung}`

)

);

const contentTemplate = getContentTemplate(`Nhân dịp sinh nhật của bạn, chúng tôi đã tặng bạn 100 điểm miễn phí. `);

Bây giờ chúng ta có thể sử dụng lại chức năng cho những người dùng khác nhau. Đối với một mẫu chứa đầy lời chào của người dùng, chúng tôi phải thực thi

const templateForMark = contentTemplate(‘Mark’);

Tất nhiên, chúng tôi cũng có thể nhận được kết quả ngay lập tức bằng cách gọi

getContentTemplate(mẫu)(người dùng);

Việc truyền mẫu cho hàm getContentTemplate sẽ chỉ trả về một hàm khác yêu cầu chúng ta truyền đối số người dùng. Ngay sau khi chuyển chuỗi người dùng đến kết quả một phần, chúng tôi sẽ nhận được đầu ra cuối cùng như thế này

Xin chào Mark

Nhân ngày sinh nhật của bạn, chúng tôi đã tặng bạn 100 điểm miễn phí

Các hàm bậc cao hơn

Trong JavaScript, hàm là giá trị hạng nhất, có nghĩa là bạn có thể chuyển chúng dưới dạng đối số, trả về và thao tác trên chúng giống như bất kỳ biến nào khác. Bạn biết cách chuyển chúng dưới dạng gọi lại trong các phương thức mảng chức năng. Bạn có thể trả về hàm (hoặc đối tượng có hàm làm giá trị) như được hiển thị trong phần về currying. Điều này mang lại rất nhiều khả năng với sự kết hợp của các lần đóng JavaScript. Trong ví dụ bên dưới, findInDatabase là một hàm được truyền cho hàm repositoryFor

kho lưu trữ constFor = (thực thể, findInDatabase) => {

const MAX_RECORDS_LIMIT = 100;

trở lại {

tìm tất cả. (bộ lọc) => (

findInDatabase(

thực thể,

{. bộ lọc, giới hạn. MAX_RECORDS_LIMIT }

)

),

};

};

Đối tượng được trả về từ phương thức repositoryFor có quyền truy cập vào bao đóng của nó và vì nó được đặt trong phương thức repositoryFor, nên nó có quyền truy cập vào biến MAXRECORDSLIMIT

Với kiến ​​thức này, bạn có thể tự mình thử triển khai cơ chế lưu vào bộ nhớ đệm đơn giản (còn được gọi là ghi nhớ). Bộ đệm có thể được lưu trữ trong phương thức repositoryFor và tất cả các phương thức trước tiên có thể kiểm tra bộ đệm và trả về giá trị được lưu trong bộ đệm nếu tìm thấy. Cố gắng sử dụng các hàm làm giá trị hạng nhất và tránh trùng lặp bằng cách sử dụng thành phần hàm. Chức năng được lưu trong bộ nhớ cache có thể được trang trí dưới dạng được lưu trong bộ nhớ cache (findInDatabase). Tôi khuyến khích bạn tìm và thực hiện nhiều cải tiến hơn cho mã này. Hãy vui vẻ khi sử dụng lập trình chức năng

Bản tóm tắt

Lập trình khai báo khuyến khích viết mã sạch và có thể tái sử dụng. Nó cho phép soạn các khối mã khai báo để xây dựng các mô-đun có khả năng kiểm tra cao và chứa mã dễ hiểu, dễ đọc. Các chức năng có thể kết hợp nhỏ cũng có nghĩa là chúng ta có thể tuân theo quy tắc DRY

Tôi hy vọng bài viết này đã cung cấp cho bạn đủ thông tin để bắt đầu khám phá các khía cạnh chức năng trong JavaScript và các ngôn ngữ khác. Tôi tin rằng bạn có thể tìm thấy các ví dụ trong mã của riêng mình, mã này có thể được cải thiện bằng cách sử dụng mã miễn phí thuần túy, không thay đổi và không có tác dụng phụ

Ví dụ lập trình chức năng là gì?

Lập trình hàm dựa trên các hàm toán học. Một số ngôn ngữ lập trình chức năng phổ biến bao gồm. Lisp, Python, Erlang, Haskell, Clojure , v.v. Ngôn ngữ chức năng thuần túy - Các loại ngôn ngữ chức năng này chỉ hỗ trợ các mô hình chức năng. Ví dụ - Haskell.

Lập trình chức năng trong thuật ngữ đơn giản là gì?

Nói chung, lập trình chức năng có nghĩa là sử dụng các chức năng sao cho hiệu quả nhất để tạo phần mềm sạch và có thể bảo trì . Cụ thể hơn, lập trình chức năng là một tập hợp các cách tiếp cận mã hóa, thường được mô tả là một mô hình lập trình.

Làm thế nào để viết js chức năng?

1 - Khai báo hàm . Để khai báo một hàm, bạn sử dụng từ khóa hàm theo sau là tên hàm bắt buộc, danh sách các tham số trong ngoặc và một cặp dấu ngoặc nhọn để viết mã hàm.