{
    "slug": "js_prototype",
    "term": "Prototypal Inheritance",
    "category": "javascript",
    "difficulty": "intermediate",
    "short": "JavaScript objects inherit from other objects via a prototype chain — class syntax is syntactic sugar over this mechanism.",
    "long": "Every JavaScript object has an internal [[Prototype]] link to another object (or null). Property lookups traverse the chain: if a property isn't on the object, JS checks its prototype, then the prototype's prototype, up to Object.prototype. ES6 class syntax creates the same prototype chain but with readable syntax — class Dog extends Animal {} sets Dog.prototype's [[Prototype]] to Animal.prototype. Key differences from classical inheritance: prototypes are live objects (modifications affect all instances), methods are shared on the prototype not copied per instance, and Object.create() enables prototype-based patterns without class syntax. PHP's class-based inheritance is classical — understanding JS prototypes helps when debugging constructor functions and instanceof checks.",
    "aliases": [
        "JavaScript prototype",
        "prototype chain",
        "prototypal inheritance"
    ],
    "tags": [
        "javascript",
        "oop",
        "fundamentals"
    ],
    "misconception": "ES6 classes replaced prototype-based inheritance in JavaScript. ES6 classes are syntactic sugar over the prototype system — they do not introduce a new inheritance model. The prototype chain still underlies all JavaScript objects; classes just provide a more familiar syntax.",
    "why_it_matters": "JavaScript's prototype chain is the underlying mechanism for inheritance and property lookup — understanding it explains class behaviour, performance of prototype methods, and how libraries extend built-ins.",
    "common_mistakes": [
        "Extending native prototypes (Array.prototype.myMethod) — pollutes the global namespace and breaks for-in loops.",
        "Confusing __proto__ (instance's prototype link) with prototype (constructor's prototype property).",
        "Creating methods inside the constructor function body — creates a new function object per instance; define on prototype.",
        "Not understanding that class syntax is syntactic sugar over prototype chains — same engine mechanics."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "js_closures",
        "js_modules"
    ],
    "prerequisites": [
        "js_closures",
        "js_class_syntax",
        "js_event_delegation"
    ],
    "refs": [
        "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain"
    ],
    "bad_code": "// Methods in constructor — new function per instance, wastes memory:\nfunction User(name) {\n    this.name = name;\n    this.greet = function() { return 'Hi, ' + this.name; }; // New function for every User\n}\n\n// Prototype method — shared across all instances:\nUser.prototype.greet = function() { return 'Hi, ' + this.name; };\n// Or with class syntax (equivalent under the hood):\nclass User { greet() { return 'Hi, ' + this.name; } }",
    "good_code": "// ES6 class — syntactic sugar over prototype chain\nclass Animal {\n  constructor(name) { this.name = name; }\n  speak() { return `${this.name} makes a noise.`; }\n}\n\nclass Dog extends Animal {\n  speak() { return `${this.name} barks.`; }\n}\n\nconst d = new Dog('Rex');\nconsole.log(d.speak()); // Rex barks.\nconsole.log(d instanceof Animal); // true\n\n// Inspect the prototype chain:\nconsole.log(Object.getPrototypeOf(d) === Dog.prototype);    // true\nconsole.log(Object.getPrototypeOf(Dog.prototype) === Animal.prototype); // true\n\n// Mixin pattern — share behaviour without inheritance\nconst Serializable = (Base) => class extends Base {\n  toJson() { return JSON.stringify(this); }\n};\nclass SerializableDog extends Serializable(Dog) {}",
    "quick_fix": "Use class syntax instead of direct prototype manipulation — class is syntactic sugar over the prototype chain but is clearer and less error-prone; understand prototype chain for debugging, avoid direct __proto__ access",
    "severity": "medium",
    "effort": "medium",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/js_prototype",
        "html_url": "https://codeclaritylab.com/glossary/js_prototype",
        "json_url": "https://codeclaritylab.com/glossary/js_prototype.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Prototypal Inheritance](https://codeclaritylab.com/glossary/js_prototype) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/js_prototype"
            }
        }
    }
}