-->
ads here

Lập trình hàm trong Javascript

advertise here
Lập trình hàm (Functional Programming - FP) là một chủ đề khá là hot trong lập trình cũng như trong Javascript. Trong bài viết lần này mình sẽ giới thiệu một số nét cơ bản về lập trình hàm và cách ứng dụng nó trong Javascript. Bài viết có nội dung chính như sau
  • Functional Programming là gì? Lợi ích của nó
  • Các khái niệm trong chính trong FP
  • Ví dụ về FP trong Javascript
    Chúng ta bắt đầu!
    enter image description here

1. Functional Programming là gì và nó có lợi ích như thế nào?

1.1. Functional Programming:

Functional Programming (FP) là một nguyên lý lập trình (Programming Paradigm). Nó là cách xây dựng phần mềm dựa trên việc kết hợp các pure functions lại với nhau, tránh việc chia sẻ state, thay đổi dữ liệu cũng như là side-effect.
Một số programming paradigm thường gặp như: Lập trình hướng đối tượng (OOP), lập trình hàm (FP) và lập trình hướng thủ tục (Procedure Programming)

1.2. Lợi ích của functional programming

Vậy chúng ta sẽ có lợi ích gì khi sử dụng Functional Programming
  • Đầu tiên, với Pure function, chúng ta đảm bảo rằng không có sự thay đổi nào xảy ra bên ngoài scope của hàm.
  • Với lập trình hàm, ta không phải bận tậm về How to do mà thay vào đó là What to do, nên đỡ phức tạp hơn
  • Nhờ các đặc tính cũng Pure function nên rất dễ dàng để test mà không phụ thuộc vào state của ứng dụng và kết qua được verify cũng rất dễ dàng
  • Và cuối cùng, Functional Programming giúp code dễ đọc và dễ hiểu hơn.

2. Các khái niệm chính trong lập trình hàm

Functional Programming dựa trên các khái niệm chính đó là Pure Function, Side Effect và Immutability. Trong phần này, chúng ta sẽ lần lượt đi vào tìm hiểu xem các khái niệm này của thể là như thế nào?

2.1. Pure function

Trong toán học, hàm (function) là khái niệm để mô tả về mối quan hệ giữa một tập các input và output với đặc tính, mỗi sự kết hợp của input sẽ tạo ra chính xác một output. Trong lập trình, khái niệm Pure function cũng tương tự, nó nhận vào dữ liệu input, tính toán ra output và không làm thay đổi nó.
Lấy ví dụ:
  • Hàm Math.random() không phải là Pure function vì mỗi lần chạy nó ra một kết quả khác nhau và ta không thể dự đoán được kết quả của nó
  • Hàm Math.min(1,2) là Pure function vì nó sẽ luôn trả về cùng một kết quả khi ta truyền vào cùng input

2.2. Side effect

Một hàm được gọi là có side effect khi nó thay đổi state của chương trình mà nằm ngoài scope của hàm. Ta lấy ví dụ như sau


let meetup = {name:'JS',isActive:true,members:49};
const scheduleMeetup = (date, place) => {  
  meetup.date = date;  
  meetup.place = place; if (meetup.members < 50)  
    meetup.isActive = false;  
}
const publishMeetup = () => {  
  if (meetup.isActive) {  
    meetup.publish = true;  
  }  
}
scheduleMeetup('today','Bnagalore');  
publishMeetup();  
console.log(meetup);
Ta thấy rằng đoạn code này có side effect vì hàm scheduleMeetup có trách nhiệm là cập nhật dateplace của meetup, nhưng đồng thời nó lại thay đổi giá trị của isActive. Mà biến isActive được sử dụng bởi hàm publishMeetup. Và vì điều này tạo ra side effect làm cho ta không thể đoán được kết quả của hàm publishMeetup khiến việc debug trở nên khó khăn hơn rất nhiều.
Tuy nhiên, side effect không phải luôn luôn không tốt, tuy nhiên chúng ta phải sử dụng chúng 1 cách cực kì cẩn thận!

2.3. Immutability

Khi data được gọi là immutable, chúng ta không thể thay đổi trạng thái của nó sau khi nó được tạo ra. Nếu bạn muốn thay đổi một immutable object, bạn không thể, điều duy nhất bạn có thể làm được là tạo ra một object mới với giá trị mới. Một hàm được gọi là Immutable khi nó khôgn thay đổi original dât mà về một giá trị mới sau khi tính toán.
Ví dụ:


const a = [1,2,3];
const b = [1,2,3];

function addElementMutable(arr, elem) {
 return arr.push(elem)
}

function addElementImmutable(arr, elem) {
 return [...arr, elem]
}

const mutableResult = addElementMutable(a, 4)
console.log(a) // [1,2,3,4]
console.log(mutableResult) // [1,2,3,4]

const immutableResult = addElementImmutable(b, 4)
console.log(b) // [1,2,3]
console.log(immutableResult) // [1,2,3,4]
Như các bạn đã thấy, 2 hàm trên đều có tác dụng thêm 1 phần tử mới vào cuối của một array. Tuy nhiên hàm addElementMutable không có tính Immutability vì sau khi thực hiện công việc của mình, nó thay đổi luôn giá trị ban đầu được truyền vào. Còn addElementImmutable sau khi thực hiện xong thì không làm thay đổi input ban đầu

3. Ví dụ về Functional Programming trong Javascript

3.1. First class Function

Một function có thể được gán và một giá trị, một thuộc tính của object cũng như một phần tử của mảng


const fn = text => console.log(text)
fn('Hello')

const obj = {
 fn(str) {
  console.log(str)
 }
}
obj.fn('Hi, how are you?')

const arr =  [text => console.log(text)]
arr[0]('Function Programming')

3.2. High Order function

High Order Function là function được truyền vào một function khác như một tham số hoặc được trả về như là output của hàm khác


const add = element => element + 1
const array = [1,2,3,4];
console.log(array.map(add)) // [2,3,4,5]

const createFunction = () => m => console.log(m)
const fn = createFunction()
console.log(fn('hello')) // hello

3.3. Immutability

Một mảng sẽ không bị thay đổi, thay vào đó ta sẽ tạo một mảng với với giá trị mới


// Add new element
const a = [1,2,3]
const b = a.concat(4) // [1,2,3,4]
// Remove element
const c = a.filter(e => e % 2 === 0) // [2]
Thay đổi object


const obj1 = {color: 'red'}
const obj2 = Object.assign({}, obj1, {color: 'blue'}) // {color: 'blue'} 

3.4. Một số thư viện sử dụng Function Programming

Reference:

Advertisement
COMMENTS ()