Pure function in JS

Hôm nay nhân ngày mát trời, chúng ta sẽ quay lại với JS nhé các bạn (Liên quan vc ^^ ). Thực ra gần đây mình không viết nhiều về JS lên lần này cố tình quay lại với nó nhé. Kì này chúng ta sẽ nói về Pure function, một cách viết function rất hữu hiệu để các bạn base code dự án nhé.
Alt Text

1. Mở đầu

Gần đây mình tình cờ đọc được một khái niệm, đó chính là Pure function. Thực ra Pure function không hề mới, mình chắc là nếu bạn đi làm 1-2-... năm đã từng làm qua rồi, đặc biệt nếu bạn nào đã xây base dự án thì có lẽ bạn sẽ phải nghĩ ra những phần Until để cho member trong team dùng lại. Những hàm dùng chung cho toàn bộ dự án đó chính là Pure function, một Function thuần túy, rất thuần túy. Còn sao lại cần Pure (Thuần túy), điều kiện như thế nào thì được coi là Pure function thì các bạn hãy xem tiếp ở phần sau nhé.

Thực ra đây là một khái niệm về Pure function, nó không phải chỉ cho JS nhé, mà nó là áp dụng chung cho các ngôn ngữ. Nó đặc biệt hữu hiệu đối với bạn nào xây base dự án hoặc thích code những hàm dùng chung cho dự án.

Gần đây mình có nhận được phản hồi là bài viết cần cho thêm hình để dễ hình dung hơn, lên từ giờ mình sẽ cố gắng tìm hình mô tả thêm có các bạn dễ nhớ nhé. (Hình trên nó cũng chưa dễ nhớ lắm ^^ - thôi kệ - nhìn nó fun fun là được).

Ok, LET GOOOOOOO!

2. Chi tiết

Trước khi vào phần giải thích mình muốn các bạn xem 2 function này và so sánh xem chúng khác nhau ở điểm nào nhé.

const add = (x, y) => x + y;

add(2, 4); // 6
let x = 2;

const add = y => {
  x += y;
};

add(4); // x === 6 (the first time)

Pure function là gì?

Như các bạn có thể thấy ở trên thì Pure không hề phụ thuộc vào các biến bên ngoài. Nhưng để cụ thể hơn, hãy đọc khái niệm của nó đã nhé:

  1. The function always returns the same result if the same arguments are passed in. It does not depend on any state, or data, change during a program’s execution. It must only depend on its input arguments.
  2. The function does not produce any observable side effects such as network requests, input and output devices, or data mutation.

Mình xin phép được dịch vắn tắt nó ra như thế này:

  1. Function luôn luôn return ra cùng một giá trị nếu nó được truyền vào tham số là các giá trị giống nhau. Nó không phụ thuộc vào bất kì trạng thái nào, dữ liệu nào khi mà nó thực thi, nó chỉ phụ thuộc duy nhất vào tham số truyền vào function.
  2. Kiểu function này không tạo ra bất kì thay đổi nào liên quan đến network request, input and output devices hay thay đổi data.

Đối với khái niệm 1: Các bạn có thể hiểu là 1 function luôn phụ thuộc vào tham số nó được truyền vào, nó không bao giờ được phụ thuộc dù là nhỏ nhất biến từ bên ngoài. Một Pure function luôn được return ra giá trị - điều này là tất nhiên vì nó đã không được change data bên ngoài thì nó phải return ra gì đó chứ. Và như vậy một Pure function sẽ cho ra cùng MỘT kết quả với N lần (N đến dương vô cùng) truyền tham số vào function. (Đấy - dễ hiểu đúng không nào các bạn ^^)

Đối với khái niệm 2: Có thể hiểu là Pure function không được làm cho data bên ngoài thay đổi, khi chạy Pure function không được làm cho app có hiện tượng gì ảnh hưởng đến các phần khác của hệ thống, hay nói cách khác là không được tạo ra các Side effects.

Mình sẽ trình bày rõ hai khái niệm này ở phần tiếp nhé. :v

Impure function là gì?

Các bạn đã biết Pure function là gì rồi, thì cũng chắc cần biết thêm Impure là gì. Impure là những function làm thay đổi data bên ngoài như ví dụ thứ 2 mình đã lấy ở bên trên nhé, khi bạn thay đổi giá trị của giá trị truyền vào function thì sẽ làm cho đầu ra của chúng ta thay đổi theo vì hàm này có phụ thuộc vào giá trị bên ngoài.

Side effects là gì?

Side effects là tất cả các sự tương tác với bên ngoài function từ bên trong nó. Nó có nghĩa là change data, call một hàm khác bên trong function (ở đây có nghĩa nếu một pure function call một Impure function thì nó không được coi là một Pure function, nhưng nếu một Pure function call một Pure function thì nó vẫn là Pure function).

Ở đây mình chỉ muốn các bạn phân biệt thật rõ 2 loại Pure function và Impure function để tránh nhầm lẫn về sau thôi nhé, chứ thực ra mỗi loại lại có chức năng riêng, nó không sinh ra để thay thế nhau, mà nó sinh ra là để hỗ trợ chúng ta viết code linh hoạt hơn thôi nhé.

Side effects có thể bao gồm một số phần mình liệt kê ở đây, nhưng hãy nhớ khái niệm bên trên mình trình bày nhé, nó là main nhất đó: Tạo một request, thay đổi data, hàm số có dùng Math.random(), lấy một cái thời gian không cố định nào đó ra, ....

Pure function dùng trong trường hợp nào?

Đây có lẽ là câu hỏi rất hay, Pure function được dùng trong trường hợp chúng ta muốn tạo ra các common code, ví dụ như là tính toán ngày chuyển nó sang một loại format khác, tính toán cộng một cái string nào đó để format con số, ..... tùy trường hợp mà chúng ta sẽ dùng như thế nào.

Nhưng dù có như thế nào thì hãy nhớ là chỉ truyền tham số và return ra giá trị thôi nhé. Bạn có thể làm gì đó với tham số tùy bạn, nhưng hãy luôn nhận thức mình đang viết một hàm dùng chung, dùng lại rất nhiều lần lên không được dùng bất kì thứ gì có liên quan đến Side effects và sau cùng hãy return giá trị đã tính toán đó ra nhé.

Tại sao Pure function là rất quan trọng?

Pure function để viết các hàm common nên có lẽ bạn đã ý thức được sự quan trọng của nó. Nó sẽ làm cho code của bạn linh hoạt hơn, có khả năng dùng lại nhiều hơn, thơm hơn (à, cái này thì còn tùy vào mũi của bạn và tâm trạng leader ngày hôm đó review code cho bạn ^^) hay là nếu các bạn muốn chỉnh common phần logic nào đó thì chỉ cần chỉnh trong Pure function nó không bao giờ gây lỗi cho phần khác ^^ ( ......... AMAZING ......... ).

3. Kết luận

Đó là tất cả những gì mình đã tìm hiểu được về Pure function, mong rằng nó có thể giúp các bạn hiểu được một phần nào đó về Pure function. Một thứ nghe có vẻ mới lạ nhưng lại được dùng rất nhiều trong các ngôn ngữ nói chung và các bạn ít nhiều cũng đã dùng nó.

SAU TẤT CẢ - Cám ơn các bạn đã luôn ủng hộ mình nhé.

4. Tham khảo

37