🧠 Concepts and Explanations

🛠 Manual Event Emitter Implementation

// Create a custom emitter
export function emitter() {
    this.events = {
        prop: []
    };
}

emitter.prototype.on = function(event, listener) {
    this.events[event] = this.events[event] || [];
    this.events[event].push(listener);
}

emitter.prototype.emit = function(event) {
    if (this.events[event]) {
        this.events[event].forEach(function(listener) {
            listener();
        });
    }
}

// Example usage:
const eventEmitter = new emitter();

eventEmitter.on("greet", function() {
    console.log("Hello, world!");
});

eventEmitter.on("greet", function() {
    console.log("A greeting event occurred!");
});

eventEmitter.emit("greet");

💡 Notes

⚠️ Magic Strings

// Example of using magic strings via config object
module.exports = {
    events: {
        GREET: 'greet'
    }
}

// Usage
eventEmitter.on(eventConfig.events.GREET, function() {
    console.log("Hello, world!");
});

🔗 Prototype Chaining

const util = require('util');

function GREET() {
    this.greeting = "Hello World";
}

// Inherit from emitter
util.inherits(GREET, emitter);

// Add custom method
GREET.prototype.greet = function(data) {
    console.log(this.greeting + " " + data);
    this.emit("greet", data);
}

// Usage
const greet1 = new GREET();

greet1.on("greet", function(data) {
    console.log("Someone greeted: " + data);
});

greet1.greet("John Doe");

📞 Call vs Apply vs Invoke

📦 Inheriting Constructor Behavior

emitter.call(this); // Run the parent constructor