Là đối tượng JavaScript hoặc chức năng?

Sự khác biệt giữa hai mô hình này là gì?

Ảnh của Joan Gamell trên Bapt

Sự khác biệt giữa OOP và lập trình chức năng là gì? . Cách tiếp cận đầu tiên sử dụng lập trình chức năng, cách tiếp cận thứ hai OOP

Giới thiệu

Trước khi chúng ta bắt đầu viết mã, tôi muốn giới thiệu nhanh với bạn về lập trình hướng đối tượng và chức năng

Cả hai đều là các mô hình lập trình khác nhau về kỹ thuật mà chúng cho phép và cấm

Có những ngôn ngữ lập trình chỉ hỗ trợ một mô hình e. g. Haskell (chức năng thuần túy)

Cũng như các ngôn ngữ hỗ trợ nhiều mô hình như JavaScript, bạn có thể sử dụng JavaScript để viết mã hướng đối tượng hoặc mã chức năng hoặc thậm chí kết hợp cả hai

Cài đặt

Trước khi chúng ta có thể đi sâu vào sự khác biệt giữa hai mô hình này, chúng ta cần thiết lập dự án

Để làm được điều đó, trước tiên chúng tôi tạo tất cả các tệp và thư mục chúng tôi cần như thế này

$ mkdir func-vs-oop
$ cd ./func-vs-oop
$ cat index.html
$ cat functional.js
$ cat oop.js

Tôi đang sử dụng lệnh cat vì nó hoạt động trên cả hệ thống Linux và Windows Powershell

Tiếp theo, chúng ta cần tạo một biểu mẫu đơn giản cho máy tính giai thừa bên trong chỉ mục. html

mục lục. html

Để cung cấp cho biểu mẫu này giao diện đẹp hơn, chúng tôi sử dụng bootstrap làm Khung CSS. Nếu bạn hiển thị HTML này trong trình duyệt, nó sẽ trông như thế này

máy tính giai thừa

Hiện tại, hình thức này sẽ không làm bất cứ điều gì

Mục tiêu của chúng tôi là triển khai logic trong đó bạn có thể nhập số lên tới 100. Sau khi nhấp vào nút "Tính toán", nó sẽ hiển thị kết quả trong div kết quả. Chúng tôi sẽ triển khai điều này theo cả cách hướng đối tượng và cách chức năng

thực hiện chức năng

Trước hết, chúng tôi sẽ tạo một tệp cho phương pháp lập trình chức năng

$ cat functional.js

Để bắt đầu, chúng ta cần một chức năng được gọi khi tải tệp này vào trình duyệt. Hàm này sẽ lấy biểu mẫu và sau đó thêm chức năng chúng ta cần vào sự kiện gửi biểu mẫu

function addSubmitHandler(tag, handler) {
const form = getElement(tag);
form.addEventListener('submit', handler);
}
addSubmitHandler('#factorial-form', factorialHandler);

Đầu tiên, chúng ta khai báo hàm có tên là addSubmitHandler

Hàm này có hai tham số, tham số đầu tiên là thẻ chúng tôi muốn tìm kiếm trong HTML của mình, tham số thứ hai là chức năng chúng tôi muốn liên kết với sự kiện gửi của Phần tử của chúng tôi

Tiếp theo, chúng ta gọi hàm này bằng cách chuyển vào #factorial-form và tên hàm factorialHandler. Dấu thăng ở phía trước thẻ cho biết rằng chúng tôi đang tìm kiếm thuộc tính id trong HTML

Mã này sẽ báo lỗi nếu bạn cố chạy nó ngay bây giờ vì cả hàm getElement và factorialHandler đều không được xác định ở bất kỳ đâu

Vì vậy, trước tiên hãy xác định hàm get Element phía trên quảng cáo của bạn SubmitHandler như thế này

function getElement(tag) {
return document.querySelector(tag);
}

Chức năng này thực sự đơn giản và chỉ trả về Phần tử HTML mà chúng tôi đã tìm thấy theo thẻ mà chúng tôi đã chuyển vào

Nhưng chúng ta sẽ sử dụng lại chức năng này sau

Bây giờ, hãy bắt đầu tạo logic cốt lõi bằng cách thêm hàm factorialHandler phía trên addSubmitHandler

function factorialHandler(event) {
event.preventDefault();
const inputNumber = getValueFromElement('#factorial');
try {
const result = calculateFactorial(inputNumber);
displayResult(result);
} catch (error) {
alert(error.message);
}
}

Chúng tôi vượt qua sự kiện và gọi ngay lập tức preventDefault. Điều này sẽ ngăn hành vi mặc định của sự kiện gửi, bạn có thể thử xem điều gì xảy ra khi nhấp vào nút mà không cần gọi preventDefault

Sau đó, chúng tôi lấy giá trị do người dùng nhập từ trường đầu vào bằng cách gọi hàm getValueFromElement. Khi nhận được số, chúng tôi cố gắng tính giai thừa bằng cách sử dụng hàm tính toán và sau đó hiển thị kết quả cho trang bằng cách chuyển kết quả cho hàm displayResult

Nếu giá trị không đúng định dạng hoặc số lớn hơn 100, chúng tôi sẽ báo lỗi và hiển thị dưới dạng cảnh báo. Đây là lý do sử dụng khối thử bắt trong trường hợp cụ thể này

Trong bước tiếp theo, chúng tôi tạo thêm hai hàm trợ giúp, getValueFromElement và displayResult. Hãy thêm chúng bên dưới hàm getElement

function getValueFromElement(tag) {
return getElement(tag).value;
}
function displayResult(result) {
getElement('#factorial-result').innerHTML = result;
}

Cả hai chức năng này đều sử dụng chức năng getElement của chúng tôi. Khả năng sử dụng lại này là một phần lý do tại sao lập trình chức năng lại hiệu quả đến vậy

Để làm cho điều này có thể tái sử dụng nhiều hơn, chúng ta có thể thêm đối số thứ hai vào displayResult, được gọi là thẻ. Để chúng ta có thể tự động thiết lập phần tử sẽ hiển thị kết quả. Nhưng trong ví dụ này, tôi đã sử dụng cách mã hóa cứng

Tiếp theo, chúng tôi tạo hàm tính toán của chúng tôi ngay trên factorialHandler

function calculateFactorial(number) {
if (validate(number, REQUIRED) && validate(number, MAX_LENGTH, 100) && validate(number, IS_TYPE, 'number')) {
return factorial(number);
} else {
throw new Error('Invalid input — either the number is to big or it is not a number');
}
}

Chúng tôi xác thực nếu đối số 'số' không trống, không cao hơn 100 và thuộc loại số. Để làm được điều đó, chúng tôi sử dụng một chức năng có tên là xác thực mà chúng tôi sẽ cần tạo tiếp theo. Nếu kiểm tra vượt qua, chúng tôi gọi hàm giai thừa và trả về kết quả của nó. Nếu các kiểm tra này không vượt qua, chúng tôi sẽ đưa ra lỗi mà chúng tôi gặp phải trong hàm factorialHandler

Trước tiên, hãy tạo hàm xác thực ngay bên dưới displayResult và ba hằng số MAX_LENGTH, IS_TYPE và REQUIRED

const MAX_LENGTH = 'MAX_LENGTH';
const IS_TYPE = 'IS_TYPE';
const REQUIRED = 'REQUIRED';
function validate(value, flag, compareValue) {
switch (flag) {
case REQUIRED:
return value.trim().length > 0;
case MAX_LENGTH:
return value <= compareValue;
case IS_TYPE:
if (compareValue === 'number') {
return !isNaN(value);
} else if (compareValue === 'string') {
return isNaN(value);
}
default:
break;
}
}

Trong chức năng này, chúng tôi sử dụng một công tắc để xác định loại xác thực nào chúng tôi sẽ thực hiện. Sau khi xác định điều đó, nó chỉ là một xác thực giá trị đơn giản

Bây giờ chúng ta sẽ thêm hàm giai thừa thực tế ngay phía trên khai báo tính toán. Đây sẽ là chức năng cuối cùng của chúng tôi cho phương pháp này

________số 8_______

Có nhiều cách khác nhau để thực hiện phép tính giai thừa, tôi đã sử dụng phương pháp lặp

Nếu bạn muốn tìm hiểu thêm về các cách tiếp cận khác nhau, tôi khuyên bạn nên xem bài viết này trên GeekForGeeks. https. //www. chuyên viên máy tính. org/chương-trình-cho-giai-số-của-một-số/

Chức năng cuối cùng. tệp js sẽ trông như thế này

chức năng. js

Theo cách tiếp cận này, chúng tôi đã làm việc độc quyền với các chức năng. Mọi chức năng đều có một mục đích duy nhất và hầu hết chúng đều có thể tái sử dụng trong các phần khác của ứng dụng

Đối với ứng dụng web đơn giản này, cách tiếp cận chức năng hơi quá mức cần thiết. Tiếp theo, chúng ta sẽ viết mã chức năng tương tự nhưng lần này là hướng đối tượng

Triển khai hướng đối tượng

Trước hết, chúng ta cần thay đổi src trong script-tag của chỉ mục của chúng ta. tập tin html như sau

Bây giờ chúng ta tạo oop. tập tin js

$ cat functional.js
0

Đối với cách tiếp cận OOP, chúng tôi muốn tạo ba lớp khác nhau, một lớp để xác thực, một lớp để tính giai thừa và một lớp để xử lý biểu mẫu

Chúng tôi bắt đầu với việc tạo lớp xử lý biểu mẫu

Biểu mẫu đầu vào

Trong hàm tạo, chúng ta lấy phần tử biểu mẫu và phần tử đầu vào và lưu trữ nó trong các biến lớp, còn được gọi là thuộc tính. Sau đó, chúng tôi thêm phương thức factorialHandler vào sự kiện gửi. Trong trường hợp này, chúng ta cần liên kết 'cái này' của lớp với phương thức

Nếu chúng tôi không làm điều đó, chúng tôi sẽ gặp lỗi tham chiếu, e. g. gọi cái này. đầu vào số. giá trị sẽ không được xác định. Sau đó, chúng ta tạo phương thức lớp factorialHandler với sự kiện làm đối số

Mã của phương thức này sẽ trông hơi quen thuộc, ví dụ: câu lệnh if kiểm tra xem giá trị đầu vào có hợp lệ hay không như chúng ta đã làm trong hàm tính toán

Trình xác thực. xác thực là một cuộc gọi đến một phương thức tĩnh bên trong Trình xác thực lớp mà chúng ta vẫn cần tạo. Chúng ta không cần khởi tạo một thể hiện mới của một đối tượng nếu chúng ta làm việc với các phương thức tĩnh. Sau khi vượt qua các xác thực, chúng tôi tạo một phiên bản mới của lớp Factorial, chuyển giá trị đầu vào và sau đó hiển thị kết quả tính toán cho người dùng

Tiếp theo, chúng ta sẽ tạo lớp Trình xác thực ngay trên lớp InputForm

Trình xác thực

Như bạn có thể thấy mọi thứ bên trong lớp này là tĩnh, phương thức xác thực cũng như ba thuộc tính. Do đó, chúng tôi không cần bất kỳ nhà xây dựng nào. Ưu điểm của việc này là chúng ta không cần khởi tạo lớp này mỗi khi muốn sử dụng nó

xác thực hầu hết giống như chức năng xác thực là chức năng của chúng tôi. js ngoại trừ việc chúng tôi làm điều này. BẮT BUỘC, cái này. MAX_LENGTH và cái này. IS_TYPE* ​​thay vì chỉ tên biến

Tiếp theo, chúng ta tạo lớp Factorial ngay bên dưới lớp Trình xác thực

yếu tố

Khi khởi tạo một thể hiện của lớp này, chúng tôi nhận được resultElement và lưu trữ nó dưới dạng thuộc tính cũng như số chúng tôi chuyển vào. Sau đó, chúng tôi gọi phương thức tính toán và lưu trữ giá trị trả về của nó trong một thuộc tính. Phương thức tính toán chứa mã giống như hàm giai thừa trong hàm. js. Cuối cùng nhưng không kém phần quan trọng, chúng ta có phương thức hiển thị đặt InternalHTML của resultElement thành số giai thừa được tính toán

hoàn chỉnh. tệp js sẽ trông như thế này

ôi. js

Chúng tôi đã tạo ba lớp khác nhau xử lý ba khía cạnh khác nhau của ứng dụng của chúng tôi

- Thẩm định. lớp xác thực

- Xử lý giai thừa. giai thừa

- Xử lý biểu mẫu. lớp InputForm

Phần kết luận

Cả hai cách tiếp cận đều là những cách hợp lệ để cấu trúc mã của bạn. Tôi thích thử những gì hoạt động tốt nhất trong các dự án khác nhau mà tôi làm việc. Hầu hết thời gian, thậm chí không thể tách biệt cả hai mô hình một cách rõ ràng như vậy.

Tôi hy vọng so sánh nhỏ này đã cho bạn hiểu cơ bản về các cách tiếp cận khác nhau trông như thế nào

JavaScript có đầy đủ chức năng không?

Javascript không phải là ngôn ngữ lập trình chức năng , hoặc ít nhất, đó không phải là mô hình định hướng chính của nó. Điều đó không có nghĩa là chúng ta không thể làm việc theo cách Chức năng bằng cách sử dụng các thư viện như Lodash, Underscore, RambdaJS hoặc chỉ sử dụng Vanilla Javascript.

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

Nếu bạn cũng xem xét các yếu tố như hỗ trợ tính bất biến, kiểu dữ liệu đại số, đối sánh mẫu, ứng dụng một phần , v.v. thì không, JavaScript *is .

JavaScript có phải là đối tượng 100% không

JavaScript không phải là ngôn ngữ hướng đối tượng dựa trên lớp . Nhưng nó vẫn có cách sử dụng lập trình hướng đối tượng (OOP).

OOP so với chức năng trong JavaScript là gì?

Trong OOP, cơ sở cơ bản là các lớp, các thể hiện của chúng có thể được lưu trữ trong các biến. Tuy nhiên, trong lập trình hàm, không có biến; . .