Subjects

All subjects Django Java Python React Spring Boot JavaScript PHP
Sign Up Free
Question 5 of 8 · Closures and Callbacks
Interview question

How do closures relate to the module pattern? Closures का module pattern से क्या रिश्ता है?

Answer

The module pattern uses closures to create private and public members. It's a way to encapsulate code and avoid polluting the global namespace.

// Basic module pattern
const calculator = (function() {
    // Private variables
    let result = 0;
    
    // Private methods
    const log = (value) => {
        console.log(`Result: ${value}`);
    };
    
    // Public methods (exposed through return object)
    return {
        add: (x) => {
            result += x;
            log(result);
            return this; // For method chaining
        },
        subtract: (x) => {
            result -= x;
            log(result);
            return this;
        },
        multiply: (x) => {
            result *= x;
            log(result);
            return this;
        },
        divide: (x) => {
            result /= x;
            log(result);
            return this;
        },
        getResult: () => result,
        reset: () => {
            result = 0;
            log(result);
            return this;
        }
    };
})();

// Usage
calculator.add(5);       // Result: 5
calculator.multiply(2);  // Result: 10
calculator.subtract(3);  // Result: 7

// Cannot access private members
console.log(calculator.result); // undefined

// Method chaining
calculator.reset().add(10).multiply(2).subtract(5); // Chainable

// More advanced module pattern with configuration
const userModule = (function() {
    // Private variables
    const users = [];
    const apiUrl = 'https://api.example.com/users';
    
    // Private methods
    const validateUser = (user) => {
        return user.name && user.email;
    };
    
    const findUserIndex = (id) => {
        return users.findIndex(user => user.id === id);
    };
    
    // Public API
    return {
        // Add user
        addUser: (user) => {
            if (!validateUser(user)) {
                throw new Error('Invalid user data');
            }
            users.push(user);
            return user;
        },
        
        // Get all users
        getUsers: () => {
            return [...users]; // Return copy to prevent external modification
        },
        
        // Get user by id
        getUser: (id) => {
            const index = findUserIndex(id);
            return index !== -1 ? { ...users[index] } : null;
        },
        
        // Update user
        updateUser: (id, updatedData) => {
            const index = findUserIndex(id);
            if (index !== -1) {
                users[index] = { ...users[index], ...updatedData };
                return users[index];
            }
            return null;
        },
        
        // Delete user
        deleteUser: (id) => {
            const index = findUserIndex(id);
            if (index !== -1) {
                users.splice(index, 1);
                return true;
            }
            return false;
        }
    };
})();

// Usage
userModule.addUser({ id: 1, name: 'John', email: 'john@gmail.com' });
userModule.addUser({ id: 2, name: 'Jane', email: 'jane@gmail.com' });

console.log(userModule.getUsers()); // [{ id: 1, ... }, { id: 2, ... }]
console.log(userModule.getUser(1)); // { id: 1, name: 'John', email: '...' }

// Private variables are protected
console.log(userModule.users);  // undefined
console.log(userModule.apiUrl); // undefined

// Modern alternative: ES6 Classes (but module pattern still relevant)
class UserModule2 {
    #users = []; // Private field
    
    addUser(user) {
        this.#users.push(user);
    }
    
    getUsers() {
        return [...this.#users];
    }
}

// Module pattern with namespace
const App = {};

App.calculator = (function() {
    let result = 0;
    return {
        add: (x) => { result += x; return result; },
        getResult: () => result
    };
})();

App.utils = (function() {
    return {
        formatDate: (date) => date.toISOString(),
        parseJSON: (str) => JSON.parse(str)
    };
})();

Interview tip: Explain that the module pattern is a way to organize code before ES6 modules. It provides privacy through closures. Mention modern alternatives like ES6 modules and classes with private fields, but emphasize that the module pattern is still widely used in legacy code and is a great example of closures in action.

Module pattern closures का use करके private और public members create करता है। Code को organize करने और global namespace को pollute करने से बचाने का तरीका है।

// Basic module pattern
const calculator = (function() {
    // Private variable
    let result = 0;
    
    // Private method
    const log = (value) => console.log(`Result: ${value}`);
    
    // Public methods
    return {
        add: (x) => {
            result += x;
            log(result);
            return this;
        },
        subtract: (x) => {
            result -= x;
            log(result);
            return this;
        },
        getResult: () => result,
        reset: () => {
            result = 0;
            return this;
        }
    };
})();

calculator.add(5);      // Result: 5
calculator.subtract(2); // Result: 3

// Private members accessible नहीं
console.log(calculator.result); // undefined

// Advanced module pattern
const userModule = (function() {
    const users = [];
    
    const validateUser = (user) => {
        return user.name && user.email;
    };
    
    return {
        addUser: (user) => {
            if (!validateUser(user)) throw new Error('Invalid');
            users.push(user);
            return user;
        },
        getUsers: () => [...users],
        getUser: (id) => users.find(u => u.id === id),
        deleteUser: (id) => {
            const index = users.findIndex(u => u.id === id);
            if (index !== -1) users.splice(index, 1);
        }
    };
})();

userModule.addUser({ id: 1, name: 'John', email: 'john@gmail.com' });
console.log(userModule.getUser(1));

// Private data protected
console.log(userModule.users); // undefined

इंटरव्यू टिप: समझाएं module pattern ES6 modules से पहले code organize करने का तरीका था। Closures के through privacy provide करता है। Modern alternatives (ES6 modules, private fields) का ज़िक्र करें, पर emphasize करें यह अभी भी widely used है।

Was this answer clear?