Ngôn ngữ tương tác cho Web
Thành thạo closures, higher-order functions và các khái niệm lập trình hàm nâng cao
Tiến độ học tập: 75% hoàn thành
Hiểu sâu về Closures và lexical scoping
Nắm vững Higher-Order Functions và callbacks
Áp dụng Function Composition và Currying
Sử dụng Memoization để tối ưu performance
Hiểu Factory Functions và Module Pattern
Làm việc với Recursion và Tail Call Optimization
Áp dụng Functional Programming Patterns
Xây dựng Custom Decorators và Middleware
Hàm có thể "nhớ" và truy cập biến từ lexical scope bên ngoài ngay cả khi scope đó đã kết thúc thực thi.
Ví dụ về Closure (Bao đóng)
1function outer(x) {2return function inner(y) {3return x + y; // "nhớ" x từ outer scope4};5}
Scope được xác định bởi vị trí khai báo trong code, không phải runtime context.
Ví dụ về Lexical Scoping
1const global = 'global';2function outer() {3const local = 'local';4return () => console.log(global, local);5}
Hàm nhận hàm khác làm argument hoặc trả về hàm, cho phép abstraction cao hơn.
Ví dụ về Higher-Order Function
1const withLogging = (fn) => (...args) => {2console.log('Calling:', fn.name);3return fn(...args);4};
Technique chuyển đổi hàm nhiều parameters thành chuỗi hàm một parameter.
Ví dụ về Currying
1const add = a => b => c => a + b + c;2const addFive = add(5);3const addFiveTen = addFive(10);
Caching kết quả của expensive function calls để tối ưu performance.
Ví dụ về Memoization
1const memoize = (fn) => {2const cache = {};3return (...args) => {4const key = JSON.stringify(args);5return cache[key] || (cache[key] = fn(...args));6};7};
Kết hợp nhiều hàm nhỏ để tạo thành hàm phức tạp hơn.
Ví dụ về Function Composition
1const compose = (f, g) => x => f(g(x));2const addOne = x => x + 1;3const double = x => x * 2;4const addOneThenDouble = compose(double, addOne);
| Khái niệm | Mục đích | Trường hợp sử dụng | Hiệu suất |
|---|---|---|---|
| Closures | Data encapsulation and state persistence | Private variables, module patterns | Medium |
| Higher-Order Functions | Function composition and abstraction | Callbacks, event handling, functional programming | High |
| Currying | Partial application and reusability | Configuration functions, specialized utilities | Medium |
| Memoization | Performance optimization through caching | Expensive calculations, recursive functions | High |
| Function Composition | Building complex operations from simple ones | Data transformation pipelines | High |
| Recursion | Solving problems by breaking them down | Tree traversal, mathematical sequences | Low |
Cleanup references khi không cần để tránh memory leaks
Ví dụ thực hành tốt
// Có thể gây memory leakfunction problematicClosure() {const largeData = new Array(1000000).fill('data');return function smallOperation() {return 'done';};}// Cách tốt hơnfunction betterClosure() {const largeData = new Array(1000000).fill('data');return function smallOperation() {// largeData = null; // Cleanup if not neededreturn 'done';};}
Factory functions provide flexibility và encapsulation
Ví dụ thực hành tốt
// Factory functionfunction createUser(name, email) {let isLoggedIn = false;return {name,email,login() { isLoggedIn = true; },logout() { isLoggedIn = false; },isActive() { return isLoggedIn; }};}const user = createUser('John', '[email protected]');
Tạo complex operations từ simple functions
Ví dụ thực hành tốt
const pipe = (...fns) => (value) => fns.reduce((acc, fn) => fn(acc), value);const processData = pipe(data => data.trim(),data => data.toLowerCase(),data => data.split(' '));
Cache results để improve performance
Ví dụ thực hành tốt
const memoize = (fn) => {const cache = {};return (...args) => {const key = JSON.stringify(args);return cache[key] || (cache[key] = fn(...args));};};const expensiveFn = memoize((n) => {// expensive calculationreturn result;});
Sử dụng var trong vòng lặp có thể gây ra kết quả không mong muốn do hoisting
// Lỗifor (var i = 0; i < 3; i++) {setTimeout(() => console.log(i), 100); // Prints 3, 3, 3}
// Đúng với letfor (let i = 0; i < 3; i++) {setTimeout(() => console.log(i), 100); // Prints 0, 1, 2}// Hoặc sử dụng IIFEfor (var i = 0; i < 3; i++) {(function(j) {setTimeout(() => console.log(j), 100); // Prints 0, 1, 2})(i);}
Closures có thể giữ references đến DOM elements, gây memory leaks
// Lỗi - memory leakfunction createHandler() {const hugeDOMElement = document.querySelector('#huge-element');return function() {console.log('handled');// hugeDOMElement is still referenced};}
// Đúng - cleanup referencesfunction createHandler() {let hugeDOMElement = document.querySelector('#huge-element');return function() {console.log('handled');hugeDOMElement = null; // Cleanup};}
Không nên dùng closures cho những operations đơn giản
// Không cần thiếtfunction createAdder(x) {return function(y) {return x + y;};}
// Đơn giản hơnconst add = (x, y) => x + y;// Hoặc sử dụng closure khi thực sự cầnconst createSpecializedAdder = (base) => (value) => base + value;