+1

Higher-order function trong Javascript

1. Higher-order function (HOF) là gì?

Trong Javascript, các function được coi như một giá trị, do đó chúng có thể được gán như một tham số hoặc là một giá trị được trả về của một function khác. Việc làm trên được gọi là sử dụng higher-order function.

Dưới đây là các ví dụ ứng dụng 2 loại triển khai HOF:

  • Truyền một function làm tham số của một function khác
  • Trả về function từ một function khác

2. Truyền một function làm tham số

Ví dụ về chức năng lọc các phần tử chẵn trong mảng. Hàm isEven là một HOF và được sự dụng làm tham số của hàm filter

const filter = (arr, fn) => {
    return arr.filter(fn);
};

const isEven = num => {
    return num % 2 === 0;
};

const evenNumbers = filter([1, 2, 3], isEven);
console.log(evenNumbers); // [2]

3. Trả về một function từ một function khác

Case 1: Phân quyền trong NodeJS

Dưới đây là đoạn code phân quyền API của mình, lúc này mình chưa biết đến khái niệm higher-order function, do đó code của mình khá khó hiểu cho người mới vào dự án.

const API_PERMISSION = {
	'/api/user': 'admin'
}

const authRolePermission = (user, role) => {
    if (user?.role !== role) {
        throw {
            message: "Not permission"
        }
    }
};

// Chưa sử dụng higher-order function
const auth = (req, res, next) => {
    try {
        authRolePermission(req.user, API_PERMISSION[req.baseUrl])

        next(); 
    } catch (error) {
        res.status(400).json({
            success: false,
            content: error
        });
    }
}

// Không nhận biết được ngay quyền truy cập API 
router.get('/api/user', auth, UserController.getCurrentUser)

Sau khi biết đến khái niệm trên, mình đã áp dụng nó vào function auth. Lúc này, mình có thể gán trực tiếp quyền truy cập API vào đoạn code routing của mình.

const authRolePermission = (user, role) => {
    if (user?.role !== role) {
        throw {
            message: "Not permission"
        }
    }
};

// Sử dụng HOF trả về một hàm
const auth = (role) => {
    return (req, res, next) => {
        try {
            authRolePermission(req.user, role)
            
            next()
        } catch (error) {
            res.status(400).json({
                success: false,
                content: error
            });
        }
    };
};

// Dễ dàng nhận biết ngay quyền truy cập API
router.get('/api/user', auth('admin'), UserController.getCurrentUser)

Case 2: Xử lý state của form trong ReactJS

Thêm 1 ví dụ nữa mình đã sử dụng higher-order function để code trở nên tổng quát hóa.

// Chưa sử dụng higher-order function
const handleEmail = (e) => {
    setEmail(e.currentTarget.value);
};

const handlePassword = (e) => {
    setPassword(e.currentTarget.value);
};
// Sử dụng HOF tổng quát hóa hàm xử lý sự kiện nhập của người dùng
const handleInput = (name) => (e) => {
    switch (name) {
        case "email":
            setEmail(e.currentTarget.value)
            break
        case "password":
            setPassword(e.currentTarget.value)
            break
        default:
            break
    }
}

const handleEmail = handleInput("email")

const handlePassword = handleInput("password")

4. Kết luận

Có rất nhiều ứng dụng HOF để giúp code trở nên clean hơn, hy vọng ví dụ của mình có thể giúp các bạn hiểu hơn về cách sử dụng HOF. Có góp ý nào về bài viết, mình xin được lắng nghe. Cảm ơn các bạn đã đọc bài viết của mình.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí