Lập trình chức năng JavaScript

Có rất nhiều bài báo, video và bài đăng trên blog về lập trình chức năng bằng các ngôn ngữ lập trình khác nhau, bao gồm cả JavaScript

Thông thường, chủ đề chính của các bài viết này là cách sử dụng các mô hình lập trình hàm khác nhau, chẳng hạn như hàm hạng nhất, đối tượng bất biến và currying.

Tuy nhiên, giá trị chính của các ngôn ngữ lập trình chức năng thuần túy là không có tác dụng phụ. Các ứng dụng một phần của các mô hình chức năng khác nhau trong các ngôn ngữ không thuần túy, chẳng hạn như JavaScript, có thể làm giảm số lượng tác dụng phụ nhưng không đảm bảo loại bỏ hoàn toàn chúng

Tác dụng phụ làm giảm khả năng mở rộng và khả năng thay thế các thành phần và nền tảng. Vì vậy, tốt hơn là giảm số lượng tác dụng phụ đến mức tối thiểu

Có hàng chục ngôn ngữ lập trình chức năng thuần túy. Một số trong số chúng khá thành công trong ngành phát triển phần mềm — ví dụ: Haskell, Elm và PureScript. Tuy nhiên, ngôn ngữ lập trình phổ biến nhất là JavaScript và nó không hoàn toàn có chức năng

Lý do chính để sử dụng JavaScript, bên cạnh tính phổ biến của nó, là hầu hết mọi trình duyệt web đều có thể chạy nó. Ngoài ra, một trong những định dạng tệp và trao đổi dữ liệu phổ biến nhất là JSON, một tập hợp con của JavaScript. Do mối quan hệ JSON/JavaScript này, việc tuần tự hóa trong JavaScript đơn giản hơn so với các ngôn ngữ lập trình khác. Theo kinh nghiệm của tôi, các ngôn ngữ lập trình hướng đối tượng thường gặp thách thức lớn nhất trong tuần tự hóa

Bất kỳ chương trình làm việc nào cũng có các tác dụng phụ như nhập/xuất, các hàm trả về thời gian hiện tại hoặc các số ngẫu nhiên

Nhưng có thể viết một phần lớn chương trình mà không sử dụng các hàm không thuần túy. Một hàm không thuần túy có thể được viết lại thành một hàm thuần túy

Ví dụ

Các chức năng thuần túy linh hoạt hơn nhiều. Nhà phát triển có thể sử dụng hàm pureAddAndPrint với các đối số thuần túy hoặc không thuần túy, chẳng hạn như console.log. Một số nền tảng có thể không có console.log và trong trường hợp đó, nhà phát triển có thể cung cấp giải pháp thay thế cho nó

Một trường hợp sử dụng khác là thử nghiệm đơn vị và nhà phát triển có thể tạo một hàm giả và chuyển nó làm đối số

cà ri

Bạn có thể nhận thấy các khai báo hàm trong bài viết này sử dụng currying. Trong hầu hết các ngôn ngữ lập trình chức năng thuần túy, một hàm chỉ có thể chấp nhận một đối số và currying là một cách để cung cấp nhiều đối số cho một hàm

Một cách khác là sử dụng một tuple làm đối số

Tuy nhiên, currying có thể đơn giản hóa các ứng dụng chức năng từng phần

Sự an toàn

Thông thường, các ngôn ngữ chức năng thuần túy cung cấp sự an toàn tốt hơn. Một hàm thuần túy không thể truy cập dữ liệu bên ngoài các đối số đã truyền. Ngược lại, một hàm không tinh khiết có thể truy cập hầu hết mọi thứ, điều này làm tăng khả năng xảy ra lỗ hổng

Một ví dụ như vậy là Log4Shell nổi tiếng. Log4j được viết bằng ngôn ngữ không thuần túy [Java] và người dùng không biết rằng nó sử dụng HTTPS để tải xuống và chạy mã. Việc triển khai Log4j thuần túy sẽ yêu cầu giao thức HTTPS làm đối số

Trong trường hợp này, người dùng có một số mức độ kiểm soát và rất có thể họ sẽ cung cấp một sơ khai thay vì một giao thức HTTPS thực tế. Các hàm thuần túy không cung cấp khả năng bảo vệ tuyệt đối, nhưng chúng có thể làm giảm đáng kể khả năng xảy ra các lỗ hổng

Tập lệnh chức năng

Có thể viết mã chức năng thuần túy bằng ngôn ngữ không thuần túy. FunctionalScript là một nỗ lực để tạo ra một tập hợp con JavaScript hoàn toàn có chức năng và tập hợp con đó không có khả năng tạo một hàm với các tác dụng phụ

Bởi vì FunctionalScript là một tập hợp con của JavaScript, nên chúng tôi không cần phát triển trình biên dịch, trình chuyển mã, trình gỡ lỗi, IDE và các công cụ phát triển khác cho ngôn ngữ này

Ngoài ra, các nhà phát triển không cần phải học một ngôn ngữ lập trình hoàn toàn mới và cách nó tương tác với các hệ thống và ngôn ngữ khác. FunctionalScript là một đặc tả mở và không có nguy cơ bị khóa nhà cung cấp

Ngay cả khi đặc tả của FunctionalScript biến mất hoàn toàn, bất kỳ mã FunctionalScript nào vẫn sẽ hoạt động như bất kỳ mã JavaScript nào khác

Vấn đề đệ quy

Hầu hết các ngôn ngữ lập trình chức năng thuần túy không có vòng lặp vì tất cả dữ liệu là bất biến

Thay vào đó, các nhà phát triển sử dụng đệ quy

Đệ quy tiêu tốn ngăn xếp và có thể gây tràn ngăn xếp trong trường hợp có quá nhiều lệnh gọi đệ quy. Các ngôn ngữ chức năng giải quyết vấn đề này bằng cách loại bỏ cuộc gọi đuôi. Lưu ý rằng trình biên dịch chỉ có thể loại bỏ lệnh gọi nếu đó là lệnh gọi hoặc thao tác cuối cùng

Ví dụ: không thể áp dụng loại bỏ cuộc gọi đuôi cho hàm factorial của chúng tôi vì thao tác cuối cùng là phép nhân thay vì factorial. Tuy nhiên, chúng ta có thể thay đổi chức năng để có thể áp dụng loại bỏ cuộc gọi đuôi

Tiêu chuẩn JavaScript [ECMAScript 6] hỗ trợ loại bỏ cuộc gọi đuôi [còn gọi là cuộc gọi đuôi phù hợp], nhưng V8 và SpiderMonkey thì không. Điều đó có nghĩa là Google Chrome, Microsoft Edge, Node. js và Firefox không hỗ trợ PTC. Vì vậy, trên thực tế, JavaScript không có PTC

Vòng lặp trong FunctionalScript

Vấn đề là các đối tượng FunctionalScript là bất biến, và như đã trình bày ở trên, chúng ta không thể sử dụng đệ quy cho các lần lặp

FunctionalScript cho phép gán lại các biến cục bộ được khai báo bằng let như một giải pháp thay thế cho vấn đề này và các biến như vậy chỉ có thể được sử dụng bên trong một hàm nơi các biến được khai báo

WebLắp ráp

WebAssugging cho phép các nhà phát triển tạo các ứng dụng web bằng hầu hết mọi ngôn ngữ lập trình. Nó có nguồn gốc từ asm. js, cũng là một tập hợp con của JavaScript

Thuận lợi

  • tốc độ thực thi mã gần như gốc,
  • các ngôn ngữ lập trình khác nhau hỗ trợ biên dịch sang WebAssugging

Nhược điểm

  • yêu cầu các bước và công cụ xây dựng bổ sung,
  • Các chương trình WebAssugging phải tương tác với DOM và API JavaScript khác bằng cách sử dụng lớp khả năng tương tác ngôn ngữ

asm. js lấy cảm hứng từ FunctionalScript như một tập hợp con của JavaScript. So sánh với Asm. js và WebAssembly, FunctionalScript là ngôn ngữ lập trình cấp cao. Về lý thuyết, có thể tạo trình biên dịch JIT và AOT từ FunctionalScript sang WebAssugging hoặc bất kỳ ngôn ngữ hợp ngữ nào khác

So với JavaScript, trình biên dịch từ FunctionalScript có thể tạo mã tối ưu hơn vì mã FunctionalScript tương tự mang tính quyết định hơn

Ví dụ: FunctionalScript có thể sử dụng bộ đếm tham chiếu thay vì bộ thu gom rác thích hợp vì dữ liệu bất biến không thể có tham chiếu vòng

Ngoài ra, các ngôn ngữ lập trình chức năng thuần túy khác, chẳng hạn như Elm, có thể sử dụng FunctionalScript làm mục tiêu biên dịch

Các hạn chế của API FunctionalScript

Như đã đề cập trước đó, FunctionalScript không thể gọi trực tiếp các chức năng có tác dụng phụ. Bởi vì API JavaScript có nhiều chức năng không thuần túy, chỉ có một tập hợp con giới hạn của API JavaScript có sẵn cho FunctionalScript

Tuy nhiên, một chương trình JavaScript có thể chuyển các hàm không thuần túy sang các mô-đun FunctionalScript

Đánh máy

FunctionalScript có nguồn gốc từ JavaScript. Tuy nhiên, có thể sử dụng chú thích kiểu JSDoc và trình biên dịch TypeScript làm trình xác thực. Ví dụ

Xem TypeScript JSDoc Reference để biết thêm chi tiết

TypeScript sử dụng hệ thống kiểu cấu trúc thay vì hệ thống kiểu danh nghĩa. Các ngôn ngữ có hệ thống loại danh nghĩa có thể gây ra sự cố đánh máy trong các dự án lớn có nhiều mô-đun của bên thứ ba. Ví dụ: hai định nghĩa của Vector3D không tương thích và cần có bộ điều hợp. Do đó, các hệ thống kiểu cấu trúc tăng cường mô đun hóa và tái sử dụng mã

Mô-đun và Gói

FunctionalScript sử dụng một nút. js trình quản lý gói [npm] và CommonJS dưới dạng hệ thống mô-đun. CommonJS dễ triển khai ngay cả khi không có trình phân tích cú pháp FunctionalScript

Bởi vì FunctionalScript là một ngôn ngữ chức năng thuần túy, một mô-đun FunctionalScript chỉ có thể tham chiếu đến một mô-đun FunctionalScript khác. Tuy nhiên, một mô-đun JavaScript có thể tham chiếu bất kỳ mô-đun FunctionalScript nào

Hiện tại, FunctionalScript không hỗ trợ Mô-đun ECMAScript và mô-đun không đồng bộ

Mô-đun JSON

CommonJS hỗ trợ tải tệp JSON dưới dạng mô-đun JavaScript. Vì JSON chỉ chứa dữ liệu nên bất kỳ tệp JSON nào cũng là một mô-đun FunctionalScript

Lưu ý rằng quy trình tải là khác nhau đối với các tệp JSON và JavaScript, ngay cả khi JSON là một tập hợp con của JavaScript

JavaScript phổ biến. js khai báo tất cả các lần xuất công khai trong module.exports

Một JSON chung. js khai báo tất cả các lần xuất công khai trong biểu thức đầu tiên

Các ứng dụng

Mã FunctionalScript có thể được sử dụng trong bất kỳ ứng dụng JavaScript/TypeScript nào. Vì mã FunctionalScript không có quyền truy cập trực tiếp vào IO, nên cùng một mã có thể được sử dụng trên các nền tảng khác nhau, ví dụ: trình duyệt web, Node. js

FunctionalScript là siêu bộ của JSON. Bởi vì nó không có tác dụng phụ, nên nó có thể được sử dụng như một JSON với các hàm và biểu thức thuần túy, chẳng hạn như trong các tệp cấu hình

Một ứng dụng khác là ngôn ngữ truy vấn thay thế cho SQL và LINQ

Xây dựng các ứng dụng web có thể kết hợp

Đừng xây dựng web nguyên khối. Sử dụng Bit để tạo và soạn các thành phần phần mềm tách rời — trong các khung yêu thích của bạn như React hoặc Node. Xây dựng các ứng dụng mô-đun và có thể mở rộng với trải nghiệm nhà phát triển mạnh mẽ và thú vị

Đưa nhóm của bạn đến Bit Cloud để lưu trữ và cộng tác trên các thành phần cùng nhau, đồng thời tăng tốc, mở rộng quy mô và chuẩn hóa đáng kể quá trình phát triển theo nhóm. Bắt đầu với các giao diện người dùng có thể kết hợp như Hệ thống thiết kế hoặc Giao diện vi mô hoặc khám phá phần phụ trợ có thể kết hợp. Hãy thử nó →

Là JavaScript OOP hoặc chức năng?

Trên thực tế, OOP có thể tồn tại mà không cần kế thừa hoặc đóng gói, do đó chúng ta có thể nói rằng JavaScript [JS] là một ngôn ngữ OOP có kế thừa và không đóng gói.

Tại sao JavaScript không phải là ngôn ngữ chức năng?

Không có định nghĩa nào được chấp nhận về ngôn ngữ lập trình chức năng . Nếu bạn định nghĩa ngôn ngữ chức năng là ngôn ngữ hỗ trợ các hàm hạng nhất và lambdas, thì đúng vậy, JavaScript *là* một ngôn ngữ chức năng.

Nút JS có phải là lập trình chức năng không?

Lập trình nút là một kiểu viết mã có nhiều chức năng hơn giúp cải thiện độ tin cậy của mã và đơn giản hóa quy trình kiểm tra và gỡ lỗi.

Ngôn ngữ nào là tốt nhất cho lập trình chức năng?

Danh sách ngôn ngữ lập trình hàm tốt nhất .
áo choàng
tiên dược
Haskell
Scala
con trăn
nhị lang

Chủ Đề