[{"data":1,"prerenderedAt":485},["ShallowReactive",2],{"topic-javascript-classes":3},{"framework":4,"topic":15,"subtopics":24},{"id":5,"description":6,"extension":7,"icon":8,"meta":9,"name":10,"order":11,"slug":8,"stem":12,"tier":13,"__hash__":14},"frameworks\u002Fframeworks\u002Fjavascript.yml","Core JavaScript interview questions covering fundamentals, functions and closures, objects and prototypes, classes and OOP, and asynchronous programming with the event loop.","yml","javascript",{},"JavaScript",1,"frameworks\u002Fjavascript",0,"_TjxyYWBq7dftU9YakX_WX1Z4wAHq9uEUUW7wXL0y0c",{"id":16,"description":17,"extension":7,"frameworkSlug":8,"meta":18,"name":19,"order":20,"slug":21,"stem":22,"__hash__":23},"topics\u002Ftopics\u002Fjavascript-classes.yml","ES6 class syntax, inheritance with extends and super, static members, private fields, getters\u002Fsetters and mixins — object-oriented JavaScript built on prototypes.",{},"Classes & OOP",5,"classes","topics\u002Fjavascript-classes","2Dc4r7D4tXqZpTXsCLGK8xzI7Sds3kxb1nsez87RxFo",[25,154,265,377],{"id":26,"title":27,"body":28,"description":32,"difficulty":35,"extension":36,"framework":10,"frameworkSlug":8,"meta":37,"navigation":38,"order":11,"path":39,"questions":40,"related":147,"seo":148,"seoDescription":149,"stem":150,"subtopic":151,"topic":19,"topicSlug":21,"updated":152,"__hash__":153},"qa\u002Fjavascript\u002Fclasses\u002Fclass-syntax.md","Class Syntax",{"type":29,"value":30,"toc":31},"minimark",[],{"title":32,"searchDepth":33,"depth":33,"links":34},"",2,[],"medium","md",{},true,"\u002Fjavascript\u002Fclasses\u002Fclass-syntax",[41,46,50,54,58,62,67,71,75,79,83,87,91,95,99,103,107,111,115,119,123,127,131,135,139,143],{"id":42,"difficulty":43,"q":44,"a":45},"what-is-class","easy","What is a class in JavaScript?","A `class` is a template for creating objects — syntactic sugar over constructor\nfunctions and prototypes that gives a cleaner, more familiar OOP syntax.\n\n```js\nclass User {\n  constructor(name) { this.name = name }\n  greet() { return `Hi, ${this.name}` }\n}\nconst u = new User('Ada')\nu.greet()  \u002F\u002F 'Hi, Ada'\n```\n\nUnder the hood, `User` is a function, `greet` lives on `User.prototype`, and\n`new User()` does the usual prototype wiring. Classes add conveniences (strict\nmode, `new`-only, non-enumerable methods) but use the same prototypal machinery.\n",{"id":47,"difficulty":35,"q":48,"a":49},"class-vs-function","How do classes differ from constructor functions?","Classes are functions with extra rules:\n\n- **Must be called with `new`** (throw otherwise).\n- **Always strict mode** inside the body.\n- **Methods are non-enumerable** (won't show in `for...in`).\n- **Not hoisted** for use (temporal dead zone).\n- Built-in `extends`\u002F`super` for inheritance.\n\n```js\nclass C {}\nC()        \u002F\u002F TypeError: Class constructor cannot be invoked without 'new'\nfunction F() {}\nF()        \u002F\u002F fine (no error)\n```\n\nThey're the same prototype mechanism with safer defaults and nicer syntax. The\n`new`-enforcement alone eliminates the classic \"forgot new\" bug.\n",{"id":51,"difficulty":43,"q":52,"a":53},"constructor-method","What is the constructor method?","A special method that runs when an instance is created with `new`, used to\ninitialize instance properties. A class can have **at most one**.\n\n```js\nclass Point {\n  constructor(x, y) {\n    this.x = x\n    this.y = y\n  }\n}\n```\n\nIf you omit it, JavaScript supplies a default empty one (or one that calls\n`super(...args)` in a subclass). The constructor is where per-instance state on\n`this` is set up.\n",{"id":55,"difficulty":35,"q":56,"a":57},"class-methods-prototype","Where do class methods live?","Regular methods are defined on the class's **`prototype`**, so all instances\nshare one copy.\n\n```js\nclass User { greet() {} }\nUser.prototype.greet           \u002F\u002F the method\nconst a = new User(), b = new User()\na.greet === b.greet            \u002F\u002F true — shared\n```\n\nThis is memory-efficient. Class fields and arrow-function fields, by contrast,\nare created **per instance** (on `this`), not on the prototype — an important\ndistinction.\n",{"id":59,"difficulty":35,"q":60,"a":61},"class-fields","What are class fields?","Class fields (public instance fields) let you declare instance properties\ndirectly in the class body, initialized per instance before the constructor body\nruns.\n\n```js\nclass Counter {\n  count = 0               \u002F\u002F instance field\n  step = 1\n  constructor(step) { if (step) this.step = step }\n}\n```\n\nFields are added to each instance (on `this`), not the prototype. They're handy\nfor default values and for arrow-function methods that bind `this`. Each\ninstance gets its own copy.\n",{"id":63,"difficulty":64,"q":65,"a":66},"arrow-class-field","hard","What is the difference between a method and an arrow-function field?","A **method** lives on the prototype (shared) and gets its `this` from the call\nsite. An **arrow-function field** is created per instance and captures `this`\nlexically (bound to the instance) — useful for callbacks.\n\n```js\nclass Btn {\n  label = 'Click'\n  handleA() { return this.label }       \u002F\u002F prototype method — `this` can be lost\n  handleB = () => this.label             \u002F\u002F instance arrow — `this` always bound\n}\nconst b = new Btn()\nconst a = b.handleA; a()   \u002F\u002F this is undefined\nconst c = b.handleB; c()   \u002F\u002F 'Click'\n```\n\nArrow fields cost memory (one per instance) but solve the \"lost `this`\" problem\nfor event handlers without manual `bind`.\n",{"id":68,"difficulty":35,"q":69,"a":70},"class-expression","What is a class expression?","A class defined as an expression (assigned to a variable or passed around),\noptionally named. Mirrors function declarations vs expressions.\n\n```js\nconst User = class { greet() {} }          \u002F\u002F anonymous class expression\nconst Animal = class Named {                \u002F\u002F named (name visible inside only)\n  whoAmI() { return Named.name }\n}\n```\n\nClass expressions are useful for conditionally creating classes, mixins (a\nfunction returning a class), and IIFE-style patterns. Like function expressions,\nthe name in a named class expression is scoped to the class body.\n",{"id":72,"difficulty":35,"q":73,"a":74},"class-hoisting","Are classes hoisted?","Class declarations are hoisted but remain in the **temporal dead zone**, so you\n**can't use them before** their declaration — unlike function declarations.\n\n```js\nnew Foo()   \u002F\u002F ReferenceError: Cannot access 'Foo' before initialization\nclass Foo {}\n```\n\nSo practically, classes behave as \"not hoisted.\" Always declare a class before\ninstantiating or extending it. This is one behavioral difference from converting\na constructor function to a class.\n",{"id":76,"difficulty":43,"q":77,"a":78},"method-shorthand","How do you define different kinds of methods in a class?","The class body supports several method forms:\n\n```js\nclass Example {\n  regular() {}                 \u002F\u002F prototype method\n  static helper() {}           \u002F\u002F on the class itself\n  get value() {}               \u002F\u002F getter\n  set value(v) {}              \u002F\u002F setter\n  async load() {}              \u002F\u002F async method\n  *generate() {}               \u002F\u002F generator method\n  [Symbol.iterator]() {}       \u002F\u002F computed\u002Fsymbol method\n}\n```\n\nAll of these (except fields) go on the prototype (or the class for `static`).\nThe class body is its own syntax — no commas between members, always strict.\n",{"id":80,"difficulty":35,"q":81,"a":82},"getters-setters-class","How do getters and setters work in classes?","`get`\u002F`set` define accessor properties on the prototype that run on read\u002Fwrite,\nso a property can be computed or validated.\n\n```js\nclass Temperature {\n  #celsius = 0\n  get celsius() { return this.#celsius }\n  set celsius(v) {\n    if (typeof v !== 'number') throw new TypeError('number required')\n    this.#celsius = v\n  }\n  get fahrenheit() { return this.#celsius * 1.8 + 32 }\n}\n```\n\nAccessors let you expose a clean property API while validating or deriving\nbehind the scenes. A getter without a setter makes a read-only property.\n",{"id":84,"difficulty":35,"q":85,"a":86},"static-method","What is a static method?","A method on the **class itself**, not on instances — called as `ClassName.method()`.\n`this` inside it is the class.\n\n```js\nclass MathUtil {\n  static square(n) { return n * n }\n}\nMathUtil.square(4)   \u002F\u002F 16\nnew MathUtil().square \u002F\u002F undefined — not on instances\n```\n\nStatics are for utilities and factory methods that don't need instance state\n(`Array.from`, `Object.keys`, `User.fromJSON`). They're inherited by subclasses\nvia the class's own prototype chain.\n",{"id":88,"difficulty":35,"q":89,"a":90},"this-in-class-method","What is this in a class method, and how can it be lost?","In a method called as `instance.method()`, `this` is the instance. Because class\nbodies are strict, extracting the method gives `this === undefined` (a\n`TypeError`), not the global object.\n\n```js\nclass Counter {\n  count = 0\n  inc() { this.count++ }\n}\nconst c = new Counter()\nconst fn = c.inc\nfn()   \u002F\u002F TypeError: Cannot read properties of undefined\n```\n\nFixes: call it on the instance (`() => c.inc()`), `bind` it, or use an\narrow-function field. This is the React class-component `this` problem.\n",{"id":92,"difficulty":43,"q":93,"a":94},"class-vs-object-literal","When should you use a class vs an object literal?","Use a **class** when you need many instances with shared behavior, inheritance,\nor encapsulated state. Use an **object literal** for a single, fixed\nconfiguration or namespace.\n\n```js\nconst config = { apiUrl: '\u002Fapi', timeout: 5000 }   \u002F\u002F one-off -> literal\nclass User { constructor(name) { this.name = name } }  \u002F\u002F many instances -> class\n```\n\nDon't reach for a class just to group functions — a module or plain object is\nsimpler. Classes shine when you're modeling entities that come in multiples.\n",{"id":96,"difficulty":43,"q":97,"a":98},"instanceof-class","How do you check if an object is an instance of a class?","Use `instanceof`, which checks whether the class's `prototype` is in the\nobject's prototype chain (so it sees inheritance).\n\n```js\nclass Animal {}\nclass Dog extends Animal {}\nconst d = new Dog()\nd instanceof Dog     \u002F\u002F true\nd instanceof Animal  \u002F\u002F true (ancestor)\n```\n\nFor cross-realm safety or duck typing, `instanceof` can be unreliable;\n`Symbol.hasInstance` can customize it, and feature checks\n(`typeof obj.bark === 'function'`) are an alternative.\n",{"id":100,"difficulty":35,"q":101,"a":102},"tostring-class","How do you customize how a class instance prints?","Override `toString` (and optionally `Symbol.toPrimitive`) to control string\nconversion in concatenation, template literals, and logging.\n\n```js\nclass Money {\n  constructor(cents) { this.cents = cents }\n  toString() { return `$${(this.cents \u002F 100).toFixed(2)}` }\n}\n`${new Money(150)}`   \u002F\u002F '$1.50'\n```\n\nWithout it, instances stringify to `[object Object]`. For richer debug output in\nNode, you can also implement `[Symbol.for('nodejs.util.inspect.custom')]`.\n",{"id":104,"difficulty":35,"q":105,"a":106},"class-strict-mode","Why are class bodies always in strict mode?","The spec runs all class code in strict mode automatically — no `'use strict'`\nneeded. This surfaces bugs (e.g. `this` is `undefined` in detached methods\ninstead of the global object) and disallows sloppy-mode footguns.\n\n```js\nclass C {\n  m() {\n    undeclared = 1   \u002F\u002F ReferenceError (strict)\n    return this      \u002F\u002F undefined when called without a receiver\n  }\n}\n```\n\nStrict mode is part of what makes classes safer than constructor functions: many\nmistakes throw loudly instead of failing silently.\n",{"id":108,"difficulty":35,"q":109,"a":110},"computed-method-names","Can class method names be computed?","Yes — use `[expression]` for dynamic method names, including well-known symbols.\n\n```js\nconst methodName = 'greet'\nclass User {\n  [methodName]() { return 'hi' }            \u002F\u002F dynamic name\n  [Symbol.iterator]() { \u002F* ... *\u002F }          \u002F\u002F symbol method\n}\nnew User().greet()   \u002F\u002F 'hi'\n```\n\nComputed names enable symbol-keyed methods (making a class iterable, thenable,\netc.) and metaprogramming where method names come from data.\n",{"id":112,"difficulty":64,"q":113,"a":114},"class-field-vs-constructor-assign","What is the difference between a class field and assigning in the constructor?","They're largely equivalent, but timing and inheritance differ. A class field\ninitializes **after `super()`** but **before** the rest of a subclass\nconstructor body; constructor assignment happens wherever you write it.\n\n```js\nclass A {\n  x = 1               \u002F\u002F field\n  constructor() { this.y = 2 }  \u002F\u002F constructor assignment\n}\n```\n\nA subtle gotcha: in a subclass, parent constructor logic runs before the child's\n**fields** are initialized, so a parent method called during construction won't\nsee the child's field values yet.\n",{"id":116,"difficulty":35,"q":117,"a":118},"private-methods-intro","Can classes have private members?","Yes — prefix with `#` for truly private fields and methods, accessible only\ninside the class.\n\n```js\nclass Account {\n  #balance = 0\n  #log(msg) { \u002F* private method *\u002F }\n  deposit(n) { this.#balance += n; this.#log('deposit') }\n  get balance() { return this.#balance }\n}\nnew Account().#balance   \u002F\u002F SyntaxError — private outside class\n```\n\nUnlike the old `_underscore` convention (just a hint), `#private` is enforced by\nthe language. (Covered in depth in the static & private members topic.)\n",{"id":120,"difficulty":35,"q":121,"a":122},"super-call-method","How do you call a parent method from a subclass?","Use `super.method()` inside the subclass — it invokes the parent's version with\nthe current instance as `this`.\n\n```js\nclass Animal { speak() { return 'sound' } }\nclass Dog extends Animal {\n  speak() { return super.speak() + ': woof' }  \u002F\u002F extend, don't replace\n}\nnew Dog().speak()   \u002F\u002F 'sound: woof'\n```\n\n`super` works in any method (not just the constructor) and is the clean\nreplacement for the manual `Parent.prototype.method.call(this)` pattern.\n",{"id":124,"difficulty":64,"q":125,"a":126},"returning-from-class-constructor","Can a class constructor return a value?","Like constructor functions, returning an **object** overrides the instance;\nreturning a primitive is ignored. But in a **derived** class you can only return\nan object or `undefined`.\n\n```js\nclass A { constructor() { return { custom: true } } }\nnew A()   \u002F\u002F { custom: true }\n\nclass B extends A { constructor() { super(); return 5 } } \u002F\u002F 5 ignored -> instance\n```\n\nThis enables caching\u002Fsingleton tricks but is rarely needed and easy to misuse.\nMost constructors should return nothing.\n",{"id":128,"difficulty":64,"q":129,"a":130},"class-toStringTag","How do you change the [object X] tag of a class?","Define a `Symbol.toStringTag` getter to control what\n`Object.prototype.toString.call(instance)` reports.\n\n```js\nclass Collection {\n  get [Symbol.toStringTag]() { return 'Collection' }\n}\nObject.prototype.toString.call(new Collection())\n\u002F\u002F '[object Collection]'\n```\n\nThis affects the default `toString` tag and some debugging output. It's a niche\nfeature, mostly used by built-ins (`Map`, `Promise`) and libraries that want\nmeaningful type tags.\n",{"id":132,"difficulty":64,"q":133,"a":134},"extends-expression","Can you extend an expression, not just a class name?","Yes — `extends` accepts any expression that evaluates to a constructor (or\n`null`). This enables **mixin factories** and dynamic base classes.\n\n```js\nconst Serializable = (Base) => class extends Base {\n  toJSON() { return { ...this } }\n}\nclass Model extends Serializable(Object) {}\n```\n\nBecause `extends \u003Cexpr>` is evaluated, you can compute the superclass — the basis\nof the mixin-via-class-factory pattern. `extends null` creates a class with no\n`Object.prototype` (advanced\u002Frare).\n",{"id":136,"difficulty":43,"q":137,"a":138},"method-chaining-class","How do you enable fluent method chaining in a class?","Return `this` from methods so calls chain on the same instance.\n\n```js\nclass Builder {\n  parts = []\n  add(p) { this.parts.push(p); return this }\n  build() { return this.parts.join('') }\n}\nnew Builder().add('a').add('b').build()   \u002F\u002F 'ab'\n```\n\nReturning the instance is the builder\u002Ffluent pattern, common in query builders\nand configuration APIs. Each method does its work and hands back `this`.\n",{"id":140,"difficulty":35,"q":141,"a":142},"class-pitfall-this-callback","Why do class methods passed as callbacks lose this?","Passing `instance.method` as a callback detaches it from the instance; when the\ncaller invokes it plainly, strict-mode `this` is `undefined`.\n\n```js\nclass Timer {\n  seconds = 0\n  tick() { this.seconds++ }   \u002F\u002F `this` lost if passed directly\n  start() {\n    setInterval(this.tick, 1000)        \u002F\u002F this is undefined\n    setInterval(() => this.tick(), 1000) \u002F\u002F arrow keeps this\n  }\n}\n```\n\nFix with an arrow wrapper, `.bind(this)`, or an arrow-function class field. This\nis the single most common class `this` bug.\n",{"id":144,"difficulty":35,"q":145,"a":146},"when-not-class","When should you avoid classes?","Avoid classes when there's no real instance state or behavior to model — a\nmodule of functions or a plain object is simpler and more idiomatic in JS.\n\n```js\n\u002F\u002F class just to namespace stateless functions\nclass StringUtils { static reverse(s) { return [...s].reverse().join('') } }\n\n\u002F\u002F plain functions \u002F module\nexport const reverse = (s) => [...s].reverse().join('')\n```\n\nFunctional and composition-based code often reads better in JavaScript than\nclass hierarchies. Use classes for genuine entities with state + behavior +\n(sometimes) inheritance — not as a default container.\n",null,{"description":32},"JavaScript class interview questions — class syntax, constructors, methods, fields, classes vs constructor functions, hoisting and common gotchas.","javascript\u002Fclasses\u002Fclass-syntax","Class Syntax & Methods","2026-06-18","nrOdp4po-2N3gRIW5xxIV4MrZLoT1Apgk_BkUHFZq_0",{"id":155,"title":156,"body":157,"description":32,"difficulty":64,"extension":36,"framework":10,"frameworkSlug":8,"meta":161,"navigation":38,"order":33,"path":162,"questions":163,"related":147,"seo":260,"seoDescription":261,"stem":262,"subtopic":263,"topic":19,"topicSlug":21,"updated":152,"__hash__":264},"qa\u002Fjavascript\u002Fclasses\u002Fclass-inheritance.md","Class Inheritance",{"type":29,"value":158,"toc":159},[],{"title":32,"searchDepth":33,"depth":33,"links":160},[],{},"\u002Fjavascript\u002Fclasses\u002Fclass-inheritance",[164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,256],{"id":165,"difficulty":43,"q":166,"a":167},"extends-keyword","How does the extends keyword work?","`class Child extends Parent` makes `Child` inherit from `Parent`: instances get\n`Parent`'s methods via the prototype chain, and `Child` itself inherits\n`Parent`'s statics.\n\n```js\nclass Animal {\n  constructor(name) { this.name = name }\n  speak() { return `${this.name} makes a sound` }\n}\nclass Dog extends Animal {\n  speak() { return `${this.name} barks` }\n}\nnew Dog('Rex').speak()   \u002F\u002F 'Rex barks'\n```\n\n`extends` wires up two chains: `Dog.prototype -> Animal.prototype` (instance\nmethods) and `Dog -> Animal` (statics). It's the clean syntax for the manual\nprototype linking you'd otherwise write.\n",{"id":169,"difficulty":35,"q":170,"a":171},"super-constructor","What does super() do in a constructor?","It calls the **parent constructor**, initializing the inherited part of the\ninstance. In a derived class you **must** call `super()` before using `this`.\n\n```js\nclass Dog extends Animal {\n  constructor(name, breed) {\n    super(name)        \u002F\u002F run Animal's constructor first\n    this.breed = breed\n  }\n}\n```\n\nThe parent constructor actually creates `this` for a derived class, which is why\n`super()` must come first. If a subclass has no constructor, a default one\ncalls `super(...args)` automatically.\n",{"id":173,"difficulty":35,"q":174,"a":175},"super-method","How do you call a parent method with super?","`super.method()` invokes the parent class's method with the current instance as\n`this` — for extending rather than fully replacing behavior.\n\n```js\nclass Dog extends Animal {\n  speak() {\n    return super.speak() + ' (woof)'   \u002F\u002F reuse parent, add to it\n  }\n}\n```\n\n`super` works in any method, getter, or static method — not just the\nconstructor. It resolves to the method on the *parent's* prototype, so overrides\ncan build on the inherited version.\n",{"id":177,"difficulty":64,"q":178,"a":179},"this-before-super","Why does using this before super() throw?","In a derived class, the instance object is created by the parent constructor via\n`super()`. Until `super()` runs, `this` is uninitialized, so accessing it throws\na `ReferenceError`.\n\n```js\nclass Dog extends Animal {\n  constructor(name) {\n    this.x = 1     \u002F\u002F ReferenceError: must call super first\n    super(name)\n  }\n}\n```\n\nThis is a real semantic difference from constructor functions (where `this`\nexists immediately). The rule ensures the parent has fully set up the object\nbefore the child modifies it.\n",{"id":181,"difficulty":43,"q":182,"a":183},"method-overriding","What is method overriding?","Defining a method in a subclass with the same name as the parent's — the\nsubclass version shadows the parent's for instances of the subclass.\n\n```js\nclass Shape { area() { return 0 } }\nclass Circle extends Shape {\n  constructor(r) { super(); this.r = r }\n  area() { return Math.PI * this.r ** 2 }   \u002F\u002F overrides Shape.area\n}\nnew Circle(2).area()   \u002F\u002F 12.56...\n```\n\nLookup finds the subclass method first. You can still reach the parent's version\nvia `super.area()`. Overriding is the basis of polymorphism.\n",{"id":185,"difficulty":35,"q":186,"a":187},"polymorphism-js","How does polymorphism work with classes?","Different subclasses override the same method, and calling that method on a\nbase-typed reference runs the actual object's version (dynamic dispatch).\n\n```js\nclass Shape { area() { return 0 } }\nclass Circle extends Shape { area() { return Math.PI * this.r ** 2 } }\nclass Square extends Shape { area() { return this.s ** 2 } }\n\nconst shapes = [new Circle(), new Square()]\nshapes.forEach(s => console.log(s.area()))  \u002F\u002F each runs its own area()\n```\n\nJavaScript dispatches methods at runtime by the object's prototype, so a\n`Shape[]` can hold mixed subclasses and each responds with its own behavior —\nclassic polymorphism.\n",{"id":189,"difficulty":35,"q":190,"a":191},"default-constructor","What is the default constructor in a subclass?","If a subclass omits a constructor, JavaScript inserts one that forwards all\narguments to the parent: `constructor(...args) { super(...args) }`.\n\n```js\nclass Animal { constructor(name) { this.name = name } }\nclass Dog extends Animal {}        \u002F\u002F implicit: constructor(...a){ super(...a) }\nnew Dog('Rex').name                \u002F\u002F 'Rex' — forwarded to Animal\n```\n\nSo you only need to write a subclass constructor when you add fields or change\nhow the parent is called. The default just chains to `super`.\n",{"id":193,"difficulty":64,"q":194,"a":195},"super-in-static","Can you use super in static methods?","Yes — in a static method, `super.method()` calls the **parent class's** static\nmethod, because static members are inherited along the constructor's own\nprototype chain.\n\n```js\nclass Base { static create() { return 'base' } }\nclass Derived extends Base {\n  static create() { return super.create() + '-derived' }\n}\nDerived.create()   \u002F\u002F 'base-derived'\n```\n\nThis works because `Derived.__proto__ === Base`, so `super` in a static context\nresolves to `Base`. Static inheritance is a real and sometimes-surprising part\nof `extends`.\n",{"id":197,"difficulty":64,"q":198,"a":199},"extends-builtins","How do you extend built-in classes like Array or Error?","Use `extends` directly — modern engines support subclassing built-ins, with\n`super()` initializing the built-in part.\n\n```js\nclass Stack extends Array {\n  peek() { return this[this.length - 1] }\n}\nconst s = new Stack()\ns.push(1, 2); s.peek()   \u002F\u002F 2 — inherits all Array methods\n\nclass AppError extends Error {\n  constructor(msg, code) { super(msg); this.name = 'AppError'; this.code = code }\n}\n```\n\nCaveat: extending `Error` historically needed `Object.setPrototypeOf(this,\nnew.target.prototype)` for correct `instanceof` after transpilation; native\nES6+ handles it. Extending `Array` also has subtle `length`\u002Findex behaviors.\n",{"id":201,"difficulty":64,"q":202,"a":203},"abstract-class-pattern","How do you create an abstract class?","JavaScript has no `abstract` keyword, so you simulate it: throw if instantiated\ndirectly (`new.target`) and throw from methods subclasses must implement.\n\n```js\nclass Shape {\n  constructor() {\n    if (new.target === Shape) throw new Error('Shape is abstract')\n  }\n  area() { throw new Error('area() must be implemented') }\n}\nclass Circle extends Shape {\n  constructor(r) { super(); this.r = r }\n  area() { return Math.PI * this.r ** 2 }\n}\n```\n\n`new.target === Shape` blocks direct instantiation; unimplemented methods throw\nat call time. It's a convention, not a language feature.\n",{"id":205,"difficulty":35,"q":206,"a":207},"inheritance-vs-composition-class","When should you prefer composition over class inheritance?","Favor composition when behavior is orthogonal or shared across unrelated types,\nor when a deep hierarchy would become rigid. Use inheritance for genuine is-a\nrelationships with stable base classes.\n\n```js\n\u002F\u002F inheritance forcing a hierarchy\nclass FlyingSwimmingDuck extends Animal {}\n\n\u002F\u002F compose capabilities\nconst duck = { ...canFly(), ...canSwim(), name: 'Donald' }\n```\n\nDeep inheritance suffers from the fragile-base-class problem; composition (mixins,\ndelegation, functions) stays flexible. \"Favor composition over inheritance\"\napplies strongly in JS.\n",{"id":209,"difficulty":64,"q":210,"a":211},"super-property-access","Can super access parent getters and fields?","`super` accesses parent **prototype** members — methods and accessors (getters\u002F\nsetters) — but **not** instance fields (those live on `this`, not the prototype).\n\n```js\nclass A {\n  get label() { return 'A' }\n  x = 1                       \u002F\u002F instance field\n}\nclass B extends A {\n  get label() { return super.label + 'B' }  \u002F\u002F 'AB'\n  getX() { return super.x }                   \u002F\u002F undefined (field, not on proto)\n}\n```\n\nSince `super` looks up the parent prototype, it sees inherited methods\u002Faccessors\nbut not own instance fields, which belong to the instance.\n",{"id":213,"difficulty":64,"q":214,"a":215},"constructor-order","What is the order of initialization in a class hierarchy?","For `new Child()`: the chain of `super()` calls runs **top-down** (parent\nconstructor first), and **fields** initialize right after that level's\n`super()` returns, before the rest of that constructor's body.\n\n```js\nclass A { constructor() { console.log('A ctor'); this.init() } init(){} }\nclass B extends A {\n  x = (console.log('B field'), 1)\n  constructor() { super(); console.log('B ctor') }\n}\n\u002F\u002F new B(): \"A ctor\" -> \"B field\" -> \"B ctor\"\n```\n\nA classic trap: a parent constructor calling an overridable method runs the\nchild override **before** the child's fields are initialized — so the override\nmay see `undefined`.\n",{"id":217,"difficulty":35,"q":218,"a":219},"instanceof-hierarchy","How does instanceof behave across an inheritance hierarchy?","`instanceof` is true for the class and all its ancestors, since each ancestor's\n`prototype` is in the chain.\n\n```js\nclass A {}\nclass B extends A {}\nclass C extends B {}\nconst c = new C()\nc instanceof C   \u002F\u002F true\nc instanceof B   \u002F\u002F true\nc instanceof A   \u002F\u002F true\n```\n\nSo `instanceof` answers \"is-a (or descends-from)\". To check the *exact* class,\ncompare `obj.constructor === C` or `Object.getPrototypeOf(obj) === C.prototype`.\n",{"id":221,"difficulty":64,"q":222,"a":223},"mixin-with-extends","How do you achieve multiple inheritance with classes?","JavaScript allows only single `extends`, so you simulate multiple inheritance\nwith **mixins** — functions that take a base class and return an extended one,\nchained together.\n\n```js\nconst Serializable = (B) => class extends B { serialize() {} }\nconst Comparable  = (B) => class extends B { compareTo() {} }\n\nclass Model extends Serializable(Comparable(Object)) {}\n```\n\nEach mixin wraps the previous class, building a linear chain that combines\nbehaviors. This is the standard pattern for \"implementing multiple interfaces\"\nof behavior in JS.\n",{"id":225,"difficulty":64,"q":226,"a":227},"super-this-binding","What is this when calling super.method()?","`this` stays the **current instance** — `super.method()` runs the parent's\nmethod but with the child instance as `this`, so it operates on the child's data.\n\n```js\nclass A { describe() { return this.constructor.name } }\nclass B extends A {\n  describe() { return super.describe() }   \u002F\u002F parent method, child `this`\n}\nnew B().describe()   \u002F\u002F 'B' — this.constructor is B\n```\n\n`super` changes *which method* runs, not the receiver. That's why an inherited\nmethod can still see the subclass's overridden properties and constructor.\n",{"id":229,"difficulty":64,"q":230,"a":231},"overriding-getter","How do you override a getter or setter in a subclass?","Redefine the accessor in the subclass. Note that defining only a getter (or only\na setter) in the child can **hide** the inherited pair, so redefine both if\nneeded.\n\n```js\nclass A {\n  get value() { return 1 }\n  set value(v) {}\n}\nclass B extends A {\n  get value() { return super.value + 1 }   \u002F\u002F extend\n  \u002F\u002F if you define only the getter, the inherited setter is shadowed away\n}\n```\n\nAccessors are properties, so overriding one member of a get\u002Fset pair replaces\nthe whole property descriptor — define both in the child to keep both behaviors.\n",{"id":233,"difficulty":35,"q":234,"a":235},"protected-convention","Does JavaScript have protected members?","No `protected` keyword. The conventions are: `_underscore` (a hint that it's\n\"internal,\" not enforced) or `#private` (truly private, but **not** accessible\nto subclasses).\n\n```js\nclass Base {\n  _internal = 1   \u002F\u002F convention: subclasses may use, but not enforced\n  #secret = 2     \u002F\u002F private — subclasses CANNOT access this\n}\n```\n\n`#private` is stricter than protected (even subclasses can't see it). For\nsubclass-accessible-but-not-public members, the `_` convention is all JS offers.\n",{"id":237,"difficulty":64,"q":238,"a":239},"calling-overridden-from-parent","Can a parent method call a method overridden by the child?","Yes — method dispatch is dynamic, so a parent method calling `this.foo()` runs\nthe **child's** override if there is one. This is the template-method pattern.\n\n```js\nclass Base {\n  process() { return this.transform(this.read()) }  \u002F\u002F calls overrides\n  read() { return 'data' }\n  transform(x) { return x }\n}\nclass Json extends Base {\n  transform(x) { return JSON.parse(x) }   \u002F\u002F parent's process() uses this\n}\n```\n\nBecause `this` is the actual instance, the inherited `process()` polymorphically\ninvokes the subclass's `transform` — powerful, but watch the constructor-order\ntrap.\n",{"id":241,"difficulty":64,"q":242,"a":243},"super-not-in-arrow","How does super behave inside an arrow function in a method?","An arrow function lexically captures `super` from its enclosing method, so\n`super.x` works inside an arrow defined within a method.\n\n```js\nclass B extends A {\n  greet() {\n    const fn = () => super.greet()   \u002F\u002F super captured lexically\n    return fn()\n  }\n}\n```\n\nLike `this`, `super` is lexical in arrows — it binds to where the arrow is\nwritten. A regular nested function, by contrast, has no `super` binding.\n",{"id":245,"difficulty":64,"q":246,"a":247},"extends-null","What does extends null do?","`class C extends null` creates a class whose instances do **not** inherit from\n`Object.prototype` — like `Object.create(null)` but as a class. It's an edge case\nand tricky (you must manually handle the prototype in the constructor).\n\n```js\nclass NullProto extends null {\n  constructor() { return Object.create(new.target.prototype) }\n}\n```\n\nInstances lack `toString`, `hasOwnProperty`, etc. It's rarely used — mainly for\ncreating prototype-less objects via class syntax. Most code never needs it.\n",{"id":249,"difficulty":35,"q":250,"a":251},"refactor-function-to-class","What changes when refactoring a constructor function to a class?","Mostly cosmetic, but watch the behavioral differences: classes **must** be called\nwith `new`, are **not usable before declaration** (TDZ), run in **strict mode**,\nand have **non-enumerable** methods.\n\n```js\n\u002F\u002F these worked with the function but not the class:\nconst f = MyFunc()        \u002F\u002F -> class: TypeError (needs new)\nnew MyClassUsedAbove()    \u002F\u002F -> ReferenceError (TDZ) if used before declaration\n```\n\nSo code that relied on calling without `new`, hoisting, or sloppy-mode behavior\ncan break. The upside is those were usually bugs the class now catches.\n",{"id":253,"difficulty":35,"q":254,"a":255},"super-multiple-levels","How does super work across multiple inheritance levels?","Each class's `super` refers to its **immediate** parent, so a method can be\nextended at each level and chained via `super`.\n\n```js\nclass A { greet() { return 'A' } }\nclass B extends A { greet() { return super.greet() + 'B' } }\nclass C extends B { greet() { return super.greet() + 'C' } }\nnew C().greet()   \u002F\u002F 'ABC'\n```\n\n`super` is statically bound to the class where the method is defined (its\n`[[HomeObject]]`), not the runtime instance — so multi-level chains resolve\ncorrectly even with overrides.\n",{"id":257,"difficulty":35,"q":258,"a":259},"composition-via-fields","How do you compose behavior by holding instances (has-a)?","Instead of inheriting, a class can **hold** another object and delegate to it —\ncomposition over inheritance.\n\n```js\nclass Engine { start() { return 'vroom' } }\nclass Car {\n  #engine = new Engine()              \u002F\u002F has-a Engine\n  start() { return this.#engine.start() }  \u002F\u002F delegate\n}\n```\n\nThis avoids tight coupling to a base class and lets you swap the held object.\nMany designs that look like inheritance are cleaner as composition with\ndelegation.\n",{"description":32},"JavaScript class inheritance interview questions — extends, super, overriding, constructor chaining, polymorphism and extending built-ins.","javascript\u002Fclasses\u002Fclass-inheritance","Inheritance with extends & super","WkrLqBmf4KArV2-vQoIEAb1a75wOTEM9nf9RxS4CGW4",{"id":266,"title":267,"body":268,"description":32,"difficulty":64,"extension":36,"framework":10,"frameworkSlug":8,"meta":272,"navigation":38,"order":273,"path":274,"questions":275,"related":147,"seo":372,"seoDescription":373,"stem":374,"subtopic":375,"topic":19,"topicSlug":21,"updated":152,"__hash__":376},"qa\u002Fjavascript\u002Fclasses\u002Fstatic-private.md","Static Private",{"type":29,"value":269,"toc":270},[],{"title":32,"searchDepth":33,"depth":33,"links":271},[],{},3,"\u002Fjavascript\u002Fclasses\u002Fstatic-private",[276,280,284,288,292,296,300,304,308,312,316,320,324,328,332,336,340,344,348,352,356,360,364,368],{"id":277,"difficulty":35,"q":278,"a":279},"static-members","What are static members?","Members (methods or fields) that belong to the **class itself**, not to\ninstances. Accessed as `ClassName.member`.\n\n```js\nclass MathUtil {\n  static PI = 3.14159\n  static square(n) { return n * n }\n}\nMathUtil.PI          \u002F\u002F 3.14159\nMathUtil.square(4)   \u002F\u002F 16\nnew MathUtil().square \u002F\u002F undefined — not on instances\n```\n\nStatics suit utilities and class-level data that don't depend on a particular\ninstance. They're shared (one copy on the class) and inherited by subclasses.\n",{"id":281,"difficulty":35,"q":282,"a":283},"static-methods-use","When do you use a static method?","For operations related to the class but not to a specific instance — most\ncommonly **factory methods** and utilities.\n\n```js\nclass User {\n  constructor(name) { this.name = name }\n  static fromJSON(json) { return new User(JSON.parse(json).name) }\n  static compare(a, b) { return a.name.localeCompare(b.name) }\n}\nconst u = User.fromJSON('{\"name\":\"Ada\"}')\n```\n\nStatic factory methods (`User.fromJSON`, `Array.from`, `Promise.resolve`) are a\ncommon alternative to overloaded constructors. `this` inside a static method is\nthe class.\n",{"id":285,"difficulty":35,"q":286,"a":287},"static-fields","What are static fields?","Class-level properties declared with `static`, shared across all instances and\nthe class — useful for constants, counters, or caches.\n\n```js\nclass Counter {\n  static count = 0           \u002F\u002F shared\n  constructor() { Counter.count++ }\n}\nnew Counter(); new Counter()\nCounter.count   \u002F\u002F 2\n```\n\nReference them via the class name (`Counter.count`), not `this` (in instance\nmethods `this` is the instance). Static fields are a newer feature; older code\nused `Class.prop = value` after the class.\n",{"id":289,"difficulty":35,"q":290,"a":291},"this-in-static","What is this inside a static method?","The **class itself** — so static methods can call sibling statics and respect\nsubclassing.\n\n```js\nclass Base {\n  static create() { return new this() }   \u002F\u002F `this` is the class\n}\nclass Sub extends Base {}\nBase.create()   \u002F\u002F Base instance\nSub.create()    \u002F\u002F Sub instance — `this` is Sub\n```\n\nBecause `this` is the concrete class, a static factory like `create()` builds an\ninstance of whichever subclass it was called on — useful for polymorphic\nfactories.\n",{"id":293,"difficulty":35,"q":294,"a":295},"private-fields","What are private fields and how do you declare them?","Fields prefixed with `#` are **truly private** — accessible only inside the\nclass body, enforced by the language (not a convention).\n\n```js\nclass Account {\n  #balance = 0\n  deposit(n) { this.#balance += n }\n  get balance() { return this.#balance }\n}\nconst a = new Account()\na.#balance         \u002F\u002F SyntaxError outside the class\na.balance          \u002F\u002F via the getter\n```\n\nUnlike the `_underscore` convention, `#private` can't be accessed or even\ndetected from outside. It's real encapsulation built into the syntax.\n",{"id":297,"difficulty":35,"q":298,"a":299},"private-vs-underscore","What is the difference between","`_name` is a **convention** — a hint that a member is internal, but it's still\nfully public and accessible. `#name` is **enforced** privacy — a SyntaxError to\naccess from outside.\n\n```js\nclass C {\n  _soft = 1     \u002F\u002F accessible: c._soft works (just \"please don't\")\n  #hard = 2     \u002F\u002F c.#hard -> SyntaxError\n}\n```\n\nPrefer `#private` for genuine encapsulation. The `_` convention persists in older\ncode and where subclass access is wanted (subclasses can't see `#private`).\n",{"id":301,"difficulty":35,"q":302,"a":303},"private-methods","Can methods be private?","Yes — prefix a method (or getter\u002Fsetter) with `#` to make it callable only from\nwithin the class.\n\n```js\nclass Service {\n  #validate(data) { return !!data }       \u002F\u002F private method\n  get #ready() { return this.#validate(this.data) }  \u002F\u002F private getter\n  submit(data) {\n    this.data = data\n    if (this.#validate(data)) { \u002F* ... *\u002F }\n  }\n}\n```\n\nPrivate methods keep internal helpers off the public API and prevent subclasses\nor callers from depending on them. They live per-class, not on the public\nprototype.\n",{"id":305,"difficulty":64,"q":306,"a":307},"static-private","Can static members be private?","Yes — combine `static` and `#` for private class-level fields and methods,\naccessible only inside the class.\n\n```js\nclass IdGenerator {\n  static #counter = 0\n  static #next() { return ++IdGenerator.#counter }\n  static create() { return { id: IdGenerator.#next() } }\n}\nIdGenerator.#counter   \u002F\u002F SyntaxError\n```\n\nStatic privates are great for internal class state (caches, counters,\nregistries) that shouldn't be touched from outside. Reference them via the class\nname inside the body.\n",{"id":309,"difficulty":64,"q":310,"a":311},"static-block","What is a static initialization block?","A `static { }` block (ES2022) runs once when the class is defined, for complex\nstatic setup that a field initializer can't express — and it can access private\nstatic members.\n\n```js\nclass Config {\n  static settings = {}\n  static {\n    const env = readEnv()             \u002F\u002F run setup logic\n    this.settings = parse(env)\n    this.#secret = deriveSecret(env)  \u002F\u002F can touch private statics\n  }\n  static #secret\n}\n```\n\nIt's the class equivalent of a one-time initializer, useful when static state\nneeds computation, multiple statements, or try\u002Fcatch at definition time.\n",{"id":313,"difficulty":64,"q":314,"a":315},"private-check","How do you check if an object has a private field (brand check)?","Use the `#field in obj` syntax (the \"ergonomic brand check\") — it returns whether\n`obj` has that private field, without throwing.\n\n```js\nclass Stream {\n  #buffer = []\n  static isStream(obj) { return #buffer in obj }\n}\nStream.isStream(new Stream())   \u002F\u002F true\nStream.isStream({})             \u002F\u002F false\n```\n\nThis is the reliable way to detect \"is this a real instance of my class\" — more\nrobust than `instanceof` (which can be spoofed via prototypes). Accessing\n`obj.#buffer` directly on a non-instance would throw, so the `in` form is used.\n",{"id":317,"difficulty":35,"q":318,"a":319},"encapsulation-benefits","Why is encapsulation with private fields valuable?","It hides internal state so callers can't depend on or corrupt it, letting you\nchange the implementation freely and enforce invariants in one place.\n\n```js\nclass Temperature {\n  #celsius = 0\n  set celsius(v) {\n    if (v \u003C -273.15) throw new RangeError('below absolute zero')\n    this.#celsius = v        \u002F\u002F validation can't be bypassed\n  }\n  get celsius() { return this.#celsius }\n}\n```\n\nWith public fields, anyone could set an invalid value directly. Private fields +\naccessors guarantee the validation runs and keep the public surface small and\nstable.\n",{"id":321,"difficulty":64,"q":322,"a":323},"private-inheritance","Are private fields inherited by subclasses?","No — `#private` fields are **not accessible** from subclasses. They belong\nstrictly to the class that declares them.\n\n```js\nclass Base { #secret = 1; getSecret() { return this.#secret } }\nclass Sub extends Base {\n  reveal() { return this.#secret }   \u002F\u002F SyntaxError — not visible\n}\n```\n\nThis is stricter than `protected` in other languages. For state subclasses need,\nuse the `_` convention or expose a protected-style accessor. Private fields are\ntruly class-local.\n",{"id":325,"difficulty":64,"q":326,"a":327},"static-inheritance","Are static members inherited?","Yes — subclasses inherit static methods and fields via the class's own prototype\nchain (`Sub.__proto__ === Base`).\n\n```js\nclass Base { static greet() { return 'hi' } }\nclass Sub extends Base {}\nSub.greet()   \u002F\u002F 'hi' — inherited static\n```\n\nInside an inherited static, `this` is the calling subclass, and `super` reaches\nthe parent's static. Static *fields* are inherited as references — careful, since\na shared static object is shared across the hierarchy.\n",{"id":329,"difficulty":35,"q":330,"a":331},"private-field-must-declare","Do you have to declare private fields before use?","Yes — every private field must be **declared in the class body**. You can't\ncreate one dynamically like a public property.\n\n```js\nclass C {\n  #x = 1            \u002F\u002F must declare\n  m() { this.#y = 2 }   \u002F\u002F SyntaxError — #y not declared\n}\n```\n\nThis is unlike public properties, which can be added anywhere. The requirement\nlets the engine know the full set of private fields at parse time (enabling the\nbrand check and strong encapsulation).\n",{"id":333,"difficulty":64,"q":334,"a":335},"singleton-static","How do you implement a singleton with static members?","Cache the instance in a private static field and expose it via a static getter\nor method, with a guarded\u002Fprivate constructor.\n\n```js\nclass Logger {\n  static #instance\n  static get instance() {\n    return Logger.#instance ??= new Logger()\n  }\n}\nLogger.instance === Logger.instance   \u002F\u002F true\n```\n\nThe private static `#instance` holds the single object; `??=` lazily creates it\nonce. (In JS, a module-level singleton is often simpler, but this is the\nclass-based form.)\n",{"id":337,"difficulty":35,"q":338,"a":339},"static-factory-vs-constructor","Why use static factory methods over constructors?","Static factories can have **descriptive names**, return cached\u002Fsubclass instances,\ndo async work indirectly, and offer multiple \"constructors\" — things a single\nconstructor can't.\n\n```js\nclass Color {\n  constructor(r, g, b) { \u002F* ... *\u002F }\n  static fromHex(hex) { \u002F* parse *\u002F return new Color(\u002F* ... *\u002F) }\n  static fromHSL(h, s, l) { \u002F* convert *\u002F return new Color(\u002F* ... *\u002F) }\n}\n```\n\nNamed factories (`fromHex`, `fromHSL`) read better than overloading one\nconstructor and let you control instance creation (caching, validation). A widely\nused OOP idiom.\n",{"id":341,"difficulty":35,"q":342,"a":343},"private-getter-setter","Can you have private getters and setters?","Yes — `get #name()` \u002F `set #name(v)` define private accessors, usable only inside\nthe class for computed private values.\n\n```js\nclass Box {\n  #w = 0; #h = 0\n  get #area() { return this.#w * this.#h }   \u002F\u002F private computed value\n  report() { return `area: ${this.#area}` }\n}\n```\n\nPrivate accessors are handy for internal derived values you don't want to expose\nor recompute manually. Like all `#` members, they're inaccessible and invisible\noutside the class.\n",{"id":345,"difficulty":64,"q":346,"a":347},"weakmap-privacy","How was privacy done before","With closures (per-instance functions) or a module-scoped **`WeakMap`** keyed by\ninstance — both hide data from outside the class.\n\n```js\nconst _balance = new WeakMap()\nclass Account {\n  constructor() { _balance.set(this, 0) }\n  deposit(n) { _balance.set(this, _balance.get(this) + n) }\n  get balance() { return _balance.get(this) }\n}\n```\n\nThe `WeakMap` lives in module scope, so only the class's methods can read it, and\nentries are garbage-collected with the instance. `#private` fields now do this\nnatively and more cleanly.\n",{"id":349,"difficulty":35,"q":350,"a":351},"static-vs-module","When should you use a static method vs a module function?","Use a **static method** when the function is conceptually tied to the class\n(factories, class-specific helpers, polymorphic via `this`). Use a **plain module\nfunction** for standalone utilities not bound to a class.\n\n```js\n\u002F\u002F tied to the class -> static\nclass Vector { static add(a, b) { \u002F* ... *\u002F } }\n\u002F\u002F generic utility -> module function\nexport function clamp(n, lo, hi) { \u002F* ... *\u002F }\n```\n\nDon't create a class full of only static methods just to namespace functions — a\nmodule is the idiomatic JS namespace. Statics belong with classes that also have\ninstances.\n",{"id":353,"difficulty":35,"q":354,"a":355},"private-method-vs-closure","What is the advantage of a private method over a closure helper?","A `#private` method lives on the class **once** (shared), whereas a closure helper\ndefined per instance (or inside the constructor) is duplicated per object. Private\nmethods give encapsulation **and** memory efficiency.\n\n```js\nclass Service {\n  #parse(x) { \u002F* shared across instances *\u002F }   \u002F\u002F one definition\n}\n\u002F\u002F vs a per-instance closure in the constructor (one function per object)\n```\n\nSo `#private` methods are usually better than closure-based privacy for classes:\nsame hiding, no per-instance function cost.\n",{"id":357,"difficulty":35,"q":358,"a":359},"enum-pattern","How do you create enum-like constants with static members?","Use static fields (often on a frozen class) to model a fixed set of named\nconstants.\n\n```js\nclass Direction {\n  static North = new Direction('N')\n  static South = new Direction('S')\n  constructor(code) { this.code = code }\n}\nObject.freeze(Direction)\nDirection.North.code   \u002F\u002F 'N'\n```\n\nJavaScript has no native `enum`, so frozen static instances (or a frozen plain\nobject `Object.freeze({ North: 'N', ... })`) are the common patterns for\nenumerations.\n",{"id":361,"difficulty":64,"q":362,"a":363},"static-this-pitfall","What is a common pitfall referencing static fields?","Inside an **instance** method, `this` is the instance, so `this.staticField` is\n`undefined` — you must use the class name (or `this.constructor`).\n\n```js\nclass C {\n  static MAX = 10\n  check(n) {\n    return n \u003C this.MAX            \u002F\u002F undefined — MAX is static\n    \u002F\u002F return n \u003C C.MAX            \u002F\u002F\n    \u002F\u002F return n \u003C this.constructor.MAX  \u002F\u002F subclass-aware\n  }\n}\n```\n\nUse `ClassName.field` for a fixed reference, or `this.constructor.field` if you\nwant subclasses to be able to override the static value.\n",{"id":365,"difficulty":64,"q":366,"a":367},"private-in-operator-guard","Why does accessing a private field on the wrong object throw?","Private fields are \"branded\" to their class. Reading `obj.#field` on an object\nthat isn't an instance throws a `TypeError`, which protects encapsulation but\nmeans you should guard with `#field in obj` first.\n\n```js\nclass A { #x = 1; static read(o) { return #x in o ? o.#x : null } }\nA.read(new A())   \u002F\u002F 1\nA.read({})        \u002F\u002F null (guarded; direct o.#x would throw)\n```\n\nThe throw-on-mismatch behavior is what makes `#field in obj` the safe brand\ncheck, and prevents one class's private accessor from working on foreign objects.\n",{"id":369,"difficulty":35,"q":370,"a":371},"freeze-class","How do you make a class's static configuration immutable?","Freeze the class (and\u002For its static objects) so static fields can't be reassigned\nafter definition.\n\n```js\nclass Config {\n  static API = '\u002Fv1'\n  static TIMEOUT = 5000\n}\nObject.freeze(Config)\nConfig.API = '\u002Fv2'   \u002F\u002F ignored (throws in strict mode)\n```\n\n`Object.freeze(Config)` locks top-level static props; nested static objects need\ntheir own freeze (it's shallow). A `static {}` block plus `Object.freeze` is a\nclean way to set up immutable class-level config.\n",{"description":32},"JavaScript static and private class member interview questions — static methods and fields, private fields and methods, static blocks, and encapsulation patterns.","javascript\u002Fclasses\u002Fstatic-private","Static & Private Members","J6BpWyoml9KkWfwfDsQHBLHqJm6SUDbQqoQYjj8Gipc",{"id":378,"title":379,"body":380,"description":32,"difficulty":64,"extension":36,"framework":10,"frameworkSlug":8,"meta":384,"navigation":38,"order":385,"path":386,"questions":387,"related":147,"seo":480,"seoDescription":481,"stem":482,"subtopic":483,"topic":19,"topicSlug":21,"updated":152,"__hash__":484},"qa\u002Fjavascript\u002Fclasses\u002Fmixins-composition.md","Mixins Composition",{"type":29,"value":381,"toc":382},[],{"title":32,"searchDepth":33,"depth":33,"links":383},[],{},4,"\u002Fjavascript\u002Fclasses\u002Fmixins-composition",[388,392,396,400,404,408,412,416,420,424,428,432,436,440,444,448,452,456,460,464,468,472,476],{"id":389,"difficulty":35,"q":390,"a":391},"what-is-mixin","What is a mixin?","A mixin is a reusable bundle of methods that can be added to multiple classes or\nobjects without using inheritance — a way to share behavior across unrelated\ntypes.\n\n```js\nconst serializable = {\n  serialize() { return JSON.stringify(this) },\n}\nclass User {}\nObject.assign(User.prototype, serializable)  \u002F\u002F mix in\nnew User().serialize()\n```\n\nMixins solve \"I need this capability in several classes that don't share a common\nparent.\" They're JavaScript's answer to multiple inheritance and interface-style\nsharing.\n",{"id":393,"difficulty":35,"q":394,"a":395},"object-assign-mixin","How do you implement a mixin with Object.assign?","Copy the mixin's methods onto a class's prototype (shared) or onto an instance.\n\n```js\nconst canFly = { fly() { return `${this.name} flies` } }\nconst canSwim = { swim() { return `${this.name} swims` } }\n\nclass Duck { constructor(name) { this.name = name } }\nObject.assign(Duck.prototype, canFly, canSwim)\n\nconst d = new Duck('Donald')\nd.fly(); d.swim()\n```\n\n`Object.assign(Class.prototype, ...mixins)` adds the methods once for all\ninstances. The mixin methods use `this`, so they operate on whatever object they\nend up on.\n",{"id":397,"difficulty":64,"q":398,"a":399},"mixin-factory","What is a mixin factory (subclass factory)?","A function that takes a base class and returns a new class extending it with\nadded behavior — composable via nesting.\n\n```js\nconst Timestamped = (Base) => class extends Base {\n  constructor(...args) { super(...args); this.createdAt = Date.now() }\n}\nconst Serializable = (Base) => class extends Base {\n  toJSON() { return { ...this } }\n}\nclass Model extends Timestamped(Serializable(Object)) {}\n```\n\nEach factory wraps the previous class, building a linear chain that combines\nfeatures — the idiomatic modern mixin pattern, since it works with `super` and\n`extends`.\n",{"id":401,"difficulty":35,"q":402,"a":403},"composition-over-inheritance","What does \"favor composition over inheritance\" mean?","Build objects by **combining small, focused pieces** (functions, mixins, held\nobjects) rather than inheriting from a deep class hierarchy — more flexible and\nless coupled.\n\n```js\n\u002F\u002F inheritance: rigid hierarchy\nclass Robot extends Machine {}\n\n\u002F\u002F composition: assemble capabilities\nconst robot = { ...withPower(), ...withMovement(), ...withSensors() }\n```\n\nInheritance locks a type into one hierarchy and suffers the fragile-base-class\nproblem. Composition lets you mix exactly the behaviors needed and swap them\nindependently. It's a core OO design principle, especially apt in JS.\n",{"id":405,"difficulty":35,"q":406,"a":407},"functional-composition","What is functional composition?","Combining simple functions so the output of one feeds the next, building complex\nbehavior from small reusable parts.\n\n```js\nconst compose = (...fns) => (x) => fns.reduceRight((acc, fn) => fn(acc), x)\nconst pipe = (...fns) => (x) => fns.reduce((acc, fn) => fn(acc), x)\n\nconst process = pipe(trim, toLowerCase, removeSpaces)\nprocess('  Hello World ')   \u002F\u002F 'helloworld'\n```\n\n`compose` applies right-to-left, `pipe` left-to-right. Function composition is\nthe functional-programming counterpart to object composition — assemble behavior\nfrom tiny, testable units.\n",{"id":409,"difficulty":35,"q":410,"a":411},"duck-typing","What is duck typing?","\"If it walks like a duck and quacks like a duck, it's a duck\" — judging an object\nby whether it has the needed methods\u002Fproperties, not by its class.\n\n```js\nfunction makeItQuack(thing) {\n  if (typeof thing.quack === 'function') return thing.quack()\n  throw new Error('not quackable')\n}\n```\n\nJavaScript leans heavily on duck typing: code checks for capabilities\n(`typeof x.then === 'function'` for thenables) rather than `instanceof`. It pairs\nnaturally with composition and mixins, where behavior matters more than lineage.\n",{"id":413,"difficulty":35,"q":414,"a":415},"mixin-vs-inheritance","When do you use a mixin instead of inheritance?","Use a mixin when a capability is shared by **unrelated** classes, or when a class\nneeds behaviors from **multiple** sources (which single inheritance can't\nprovide).\n\n```js\n\u002F\u002F both need serialization, but aren't otherwise related\nObject.assign(User.prototype, Serializable)\nObject.assign(Invoice.prototype, Serializable)\n```\n\nUse inheritance for a genuine is-a relationship with a single, stable parent. If\nyou find yourself wanting to extend two parents, that's a mixin (or composition)\nsituation.\n",{"id":417,"difficulty":64,"q":418,"a":419},"mixin-conflicts","What happens when two mixins define the same method?","With `Object.assign`, the **last** mixin wins silently — no error, the earlier\nmethod is overwritten.\n\n```js\nconst a = { run() { return 'a' } }\nconst b = { run() { return 'b' } }\nObject.assign(target, a, b)\ntarget.run()   \u002F\u002F 'b' — collision resolved by order, silently\n```\n\nYou must manage conflicts yourself: rename methods, namespace them, or resolve\nexplicitly. This is the trade-off mixins make for flexibility — no automatic\nconflict detection like some languages' traits.\n",{"id":421,"difficulty":64,"q":422,"a":423},"stateful-mixins","How do mixins handle state?","Method-only mixins are simplest. For state, use a **mixin factory** (so it can run\nconstructor logic via `super`) or initialize state in the mixin's methods —\nobject-literal mixins can't easily set up per-instance fields.\n\n```js\nconst Counter = (Base) => class extends Base {\n  #count = 0\n  increment() { return ++this.#count }\n}\nclass Widget extends Counter(Object) {}\n```\n\nThe class-factory form integrates with the constructor chain, so it can declare\nfields and call `super()`. Plain `Object.assign` mixins are best for stateless\nbehavior.\n",{"id":425,"difficulty":35,"q":426,"a":427},"delegation","What is delegation as a composition technique?","Holding another object and **forwarding** calls to it (has-a), instead of\ninheriting — a flexible alternative to subclassing.\n\n```js\nclass Engine { start() { return 'vroom' } }\nclass Car {\n  #engine = new Engine()\n  start() { return this.#engine.start() }   \u002F\u002F delegate\n}\n```\n\nDelegation lets you swap the held object, compose multiple collaborators, and\navoid tight base-class coupling. It's the runtime sibling of prototypal\ndelegation, done explicitly with object fields.\n",{"id":429,"difficulty":64,"q":430,"a":431},"traits","What are \"traits\" and how do they differ from mixins?","Traits are like mixins but with stricter conflict handling — they require explicit\nresolution when methods clash, rather than silently overwriting. JavaScript has no\nbuilt-in traits; libraries emulate them.\n\n```js\n\u002F\u002F emulated trait: throw on conflict instead of silent override\nfunction applyTrait(target, trait) {\n  for (const k of Object.keys(trait)) {\n    if (k in target) throw new Error(`conflict: ${k}`)\n    target[k] = trait[k]\n  }\n}\n```\n\nThe distinction is mostly academic in JS — both share behavior horizontally; the\ndifference is conflict policy. Plain `Object.assign` mixins are the common\nreality.\n",{"id":433,"difficulty":35,"q":434,"a":435},"react-hooks-composition","How is composition used outside of classes?","Modern JS increasingly composes **functions** rather than objects — e.g. React\nhooks, higher-order functions, and middleware pipelines all build behavior by\ncombining functions.\n\n```js\n\u002F\u002F composing custom hooks (function composition of behavior)\nfunction useUser(id) {\n  const data = useFetch(`\u002Fusers\u002F${id}`)\n  const auth = useAuth()\n  return { ...data, isOwner: auth.id === id }\n}\n```\n\nThe trend in JS is away from class hierarchies toward composing small functions\nand objects. Understanding composition matters even if you rarely write classes.\n",{"id":437,"difficulty":64,"q":438,"a":439},"mixin-super","Can a mixin call the base class's method?","Yes — if it's a **class-factory mixin**, it can use `super.method()` to call the\nwrapped base class, enabling cooperative behavior.\n\n```js\nconst Loud = (Base) => class extends Base {\n  speak() { return super.speak().toUpperCase() }  \u002F\u002F augments base\n}\nclass Animal { speak() { return 'hi' } }\nclass Dog extends Loud(Animal) {}\nnew Dog().speak()   \u002F\u002F 'HI'\n```\n\nObject-literal mixins can't use `super` (no base class), but class-factory mixins\nsit in the prototype chain, so `super` works — letting mixins decorate inherited\nmethods.\n",{"id":441,"difficulty":35,"q":442,"a":443},"object-composition-pattern","How do you compose objects with factory functions?","Build an object by spreading capability objects into it — each capability is a\nsmall factory that closes over shared state.\n\n```js\nconst hasName = (name) => ({ getName: () => name })\nconst canGreet = (self) => ({ greet: () => `Hi, ${self.getName()}` })\n\nfunction createPerson(name) {\n  const self = { ...hasName(name) }\n  return { ...self, ...canGreet(self) }\n}\n```\n\nThis factory-composition style avoids `class`\u002F`this`\u002F`new` entirely, assembling\nbehavior from functions. It's popular in functional-leaning JS codebases.\n",{"id":445,"difficulty":35,"q":446,"a":447},"interface-segregation-js","How do mixins relate to interfaces?","JavaScript has no `interface` keyword, but mixins act like **implementable\ninterfaces of behavior** — a class can \"implement\" several capabilities by mixing\nthem in, similar to implementing multiple interfaces.\n\n```js\nclass FileLogger extends Loggable(Serializable(Object)) {}\n\u002F\u002F \"implements\" Loggable and Serializable behaviors\n```\n\nWhere a typed language declares `implements A, B`, JS mixes the actual behavior\nin. (TypeScript adds real `interface`\u002F`implements` on top for type checking.)\n",{"id":449,"difficulty":35,"q":450,"a":451},"avoid-deep-hierarchy","What problems come from deep inheritance hierarchies?","Deep hierarchies cause the **fragile base class** problem (a base change breaks\nfar-off subclasses), tight coupling, rigidity (a type is stuck in one tree), and\n\"yo-yo\" debugging across many levels.\n\n```js\n\u002F\u002F hard to change Animal without risking Dog, Puppy, ServiceDog, ...\nclass ServiceDog extends Puppy extends Dog extends Animal {}\n```\n\nFlatten with composition: give objects the behaviors they need from small mixins\u002F\ncollaborators instead of inheriting a long chain. Two or three levels is usually\na practical ceiling.\n",{"id":453,"difficulty":35,"q":454,"a":455},"composition-testing","Why is composition easier to test than inheritance?","Composed pieces are small, independent units you can test in isolation and swap\nwith fakes. Inheritance ties behavior to a hierarchy, so testing a subclass drags\nin the whole base.\n\n```js\nclass Order {\n  constructor(payment) { this.payment = payment }   \u002F\u002F injected collaborator\n  checkout() { return this.payment.charge() }\n}\nnew Order({ charge: () => 'mock' }).checkout()   \u002F\u002F easy to fake\n```\n\nDependency injection + composition lets you substitute collaborators in tests.\nThat testability is a major reason \"composition over inheritance\" holds.\n",{"id":457,"difficulty":35,"q":458,"a":459},"assign-vs-spread-mixin","What is the difference between mixing into the prototype vs each instance?","Mixing into the **prototype** (`Object.assign(Class.prototype, mixin)`) shares one\ncopy across all instances. Mixing into each **instance** (in the constructor)\ngives every object its own copy — more memory, but allows per-instance\ncustomization.\n\n```js\nObject.assign(User.prototype, mixin)   \u002F\u002F shared (efficient)\n\u002F\u002F vs\nclass User { constructor() { Object.assign(this, mixin) } }  \u002F\u002F per-instance\n```\n\nPrefer prototype mixing for shared stateless behavior. Per-instance mixing is for\nwhen each object needs independently modifiable methods\u002Fstate.\n",{"id":461,"difficulty":64,"q":462,"a":463},"higher-order-component","How does the decorator\u002Fwrapper pattern relate to composition?","A decorator wraps an object\u002Ffunction to add behavior while preserving the\ninterface — composition by **layering**.\n\n```js\nconst withLogging = (fn) => (...args) => {\n  console.log('calling', fn.name, args)\n  return fn(...args)\n}\nconst loggedFetch = withLogging(fetch)\n```\n\nHigher-order functions (and React HOCs) wrap to extend behavior without modifying\nthe original — the same compositional idea as class-factory mixins, applied to\nfunctions\u002Fcomponents.\n",{"id":465,"difficulty":64,"q":466,"a":467},"when-mixin-bad","What are the downsides of mixins?","Mixins can cause **name collisions** (silent overrides), make it unclear where a\nmethod came from (implicit behavior), create hidden coupling between mixin and\nhost, and complicate `this` reasoning.\n\n```js\nObject.assign(C.prototype, a, b, c)  \u002F\u002F which mixin defined `process`? unclear\n```\n\nUse them sparingly and namespace methods to reduce clashes. Often plain\ncomposition\u002Fdelegation (an explicit collaborator object) is clearer than mixing\nmethods into a prototype.\n",{"id":469,"difficulty":35,"q":470,"a":471},"capability-pattern","How do you give an object only the capabilities it needs?","Compose exactly the behaviors required, rather than inheriting a broad base that\nincludes extras.\n\n```js\nconst readable = (store) => ({ read: (k) => store[k] })\nconst writable = (store) => ({ write: (k, v) => { store[k] = v } })\n\nconst readOnly = { ...readable(data) }              \u002F\u002F only read\nconst readWrite = { ...readable(data), ...writable(data) }\n```\n\nThis \"interface segregation\" via composition keeps objects minimal and intention-\nrevealing — you grant precisely the capabilities needed, avoiding the bloat of a\ndo-everything base class.\n",{"id":473,"difficulty":64,"q":474,"a":475},"this-in-mixin","How does this behave inside a mixin method?","A mixin method's `this` is whatever object it's called on (the host instance), so\nit operates on the host's data — that's what makes mixins reusable across types.\n\n```js\nconst describable = {\n  describe() { return `${this.type}: ${this.name}` }\n}\nObject.assign(Product.prototype, describable)\nnew Product().describe()   \u002F\u002F uses the Product's this.type \u002F this.name\n```\n\nThe mixin doesn't care which class it's in — it just uses `this`. Avoid arrow\nfunctions in object-literal mixins (they'd capture the wrong `this`); use regular\nmethod shorthand.\n",{"id":477,"difficulty":35,"q":478,"a":479},"prefer-composition-summary","How do you decide between inheritance, mixins, and composition?","A practical rule of thumb:\n\n- **Inheritance** — a true, stable **is-a** with one parent (`Circle` is a\n  `Shape`).\n- **Mixins** — a **capability** shared by unrelated classes\n  (`Serializable`, `Comparable`).\n- **Composition\u002Fdelegation** — a **has-a** relationship or swappable collaborator\n  (`Car` has an `Engine`).\n\n```js\nclass Circle extends Shape {}                 \u002F\u002F is-a\nObject.assign(Circle.prototype, Serializable) \u002F\u002F capability\nclass Car { #engine = new Engine() }          \u002F\u002F has-a\n```\n\nDefault to composition; reach for inheritance only for genuine is-a hierarchies,\nand mixins for cross-cutting behaviors.\n",{"description":32},"JavaScript mixins and composition interview questions — sharing behavior without inheritance, mixin factories, composition over inheritance, and duck typing.","javascript\u002Fclasses\u002Fmixins-composition","Mixins & Composition","aHIXUIyhSVDUwHvZ-v5yI9JeKd24BUHXfIhRZezvWQU",1781808674571]