Currying function là gì
Thứ năm, 12/12/2019 | 00:00 GMT+7 Nếu bạn viết mã bằng JavaScript, rất có thể bạn đã gặp phải thuật ngữ closure , đây là một khái niệm hữu ích nhưng thường gây nhầm lẫn. Nhưng đóng cửa là gì?
Nhưng chính xác thì điều này nghĩa là gì? Môi trường từ vựng bao gồm bất kỳ biến local nào trong phạm vi của hàm khi hàm được tạo. Một bao đóng cho phép người ta tham chiếu đến tất cả các biến local của một hàm ở trạng thái chúng được tìm thấy. Điều này về cơ bản đạt được bằng cách xác định một chức năng bên trong một chức năng khác, chức năng này bên trong một chức năng về mặt kỹ thuật là sự đóng lại. Mỗi khi hàm cha được gọi, một bối cảnh thực thi mới được tạo ra, giữ một bản sao mới của tất cả các biến local . Các biến local này có thể được tham chiếu trong phạm vi toàn cục bằng cách liên kết chúng với các biến được khai báo trên toàn cục hoặc trả về bao đóng từ hàm mẹ. Một ví dụ cơ bản sẽ có định dạng tương tự như sau: Cũng có thể có một bao đóng trả về một số phương thức như được hiển thị bên dưới: function closure(){ function first() { console.log('I was declared first')} function second() { console.log('I was declared second')} function third() { console.log('I was declared third')} return [first, second, third] }Để tham chiếu đến từng phương thức này, ta sẽ gán bao đóng của ta cho một biến toàn cục, sau đó sẽ trỏ đến một mảng các phương thức được hiển thị. Mỗi phương thức sau đó có thể được gán cho các tên biến duy nhất để đưa chúng vào phạm vi toàn cục như hình dưới đây. Đến đây, chúng có thể được gọi. let f = closure() let one = f[0] let two = f[1] let three = f[2] one() // logs I was declared first two() // logs I was declared second three() // logs I was declared thirdTại sao sử dụng Closures?Bạn có thể tự hỏi tại sao một người lại gặp khó khăn khi đóng cửa. Chà, đóng cửa có một số công dụng và lợi thế. Trước khi giới thiệu Lớp trong ES6, các bao đóng cung cấp một phương tiện tạo quyền riêng tư giống như lớp tương tự như được sử dụng trong Lập trình hướng đối tượng, cho phép ta mô phỏng các phương thức riêng. Đây được gọi là module pattern và nó cho phép ta viết mã dễ bảo trì với việc giảm ô nhiễm không gian tên và nhiều khả năng tái sử dụng hơn. Hãy xem xét một trường hợp mà điều này được thực hiện: var makeCounter = function() { var privateCounter = 0; function changeBy(val) { privateCounter += val; } return { increment: function() { changeBy(1); }, decrement: function() { changeBy(-1); }, value: function() { return privateCounter; } } }; var counter1 = makeCounter(); var counter2 = makeCounter(); counter1.value(); // returns 0 counter1.increment(); // adds 1 counter1.increment(); // adds 1 counter1.value(); // returns 2 counter1.decrement(); //subtracts 1 counter1.value(); // returns 1 counter2.value(); // returns 0Trong ví dụ trên, ta đã khai báo một hàm makeCounter là một hàm công khai có quyền truy cập vào một số biến private bên trong nó như privateCounter và các hàm thao tác với nó. Điều này bắt chước hành vi tạo makeCounter dưới dạng một lớp với chính nó được xây dựng trong fuctionality và biến. Có thể thấy điều này khi ta tạo hai bộ đếm khác nhau, bộ counter1 và bộ counter2 . Mỗi bộ đếm độc lập với bộ đếm khác và tham chiếu đến một version khác nhau của các biến. Closures cũng cho phép ta sử dụng các hàm để tạo các hàm khác bổ sung một giá trị cụ thể cho đối số của chúng. Trong trường hợp này, hàm cha cho phép hành vi này được gọi là một function factory vì nó về cơ bản tạo ra các hàm khác. Sử dụng các nhà máy chức năng, ta có thể đạt được một hành vi được gọi là Currying , mà ta sẽ đề cập trong phần tiếp theo. Cà ri là gìCurrying là mô hình của các chức năng ngay lập tức đánh giá và trả về các chức năng khác. Điều này được thực hiện bởi thực tế là các hàm Javascript là các biểu thức có thể trả về các hàm khác. Các hàm có cấu trúc được xây dựng bằng cách đóng chuỗi bằng cách xác định và trả về đồng thời các hàm bên trong của chúng ngay lập tức. Đây là một ví dụ về món cà ri: let greeting = function (a) { return function (b) { return a + ' ' + b } } let hello = greeting('Hello') let morning = greeting('Good morning') hello('Austin') // returns Hello Austin hello('Roy') // returns Hello Roy morning('Austin') // returns Good morning Austin morning('Roy') //returns Good Morning RoyHai hàm được tạo từ greeting ( hello và morning ), mỗi hàm trả về sẽ xử lý các đầu vào được cung cấp để tạo ra một câu chào. Họ cũng có một đối số là tên của người được chào đón. Trong trường hợp trên, câu chào cũng được sử dụng như một nhà máy chức năng với hai chức năng hello và morning được tạo ra từ nó. Hàm bên trong cũng có thể được gọi sau lần gọi đầu tiên như sau: greeting('Hello There')('General Kenobi') //returns Hello There General KenobiCurrying được coi là một phần của lập trình hàm và vì vậy các hàm curry như vậy có thể dễ dàng được viết bằng cách sử dụng cú pháp hàm mũi tên trong ES6 và các version Javascript mới hơn để có mã rõ ràng, thanh lịch hơn: let greeting = (a) => (b) => a + ' ' + b greeting('Hello There')('General Kenobi') //returns Hello There General KenobiKết luậnMặc dù các bao đóng có thể không được sử dụng phổ biến vì các lớp được kết hợp trong Javascript trong ES6, nhưng chúng vẫn có vị trí của bạn khi nói đến việc viết mã sạch có thể tái sử dụng. Closures và currying cũng là những khái niệm quan trọng cần hiểu khi nói đến lập trình chức năng, nơi chúng về cơ bản phục vụ một mục đích tương tự như các phương thức riêng trong Lập trình hướng đối tượng. Tags: Các tin liên quan Cách gói một gói JavaScript Vanilla để sử dụng trong React |