[{"data":1,"prerenderedAt":141},["ShallowReactive",2],{"qa-\u002Fjavascript\u002Fclasses\u002Fmixins-composition":3},{"page":4,"siblings":125,"blog":138},{"id":5,"title":6,"body":7,"description":11,"difficulty":14,"extension":15,"framework":16,"frameworkSlug":17,"meta":18,"navigation":19,"order":20,"path":21,"questions":22,"related":116,"seo":117,"seoDescription":118,"stem":119,"subtopic":120,"topic":121,"topicSlug":122,"updated":123,"__hash__":124},"qa\u002Fjavascript\u002Fclasses\u002Fmixins-composition.md","Mixins Composition",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"hard","md","JavaScript","javascript",{},true,4,"\u002Fjavascript\u002Fclasses\u002Fmixins-composition",[23,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112],{"id":24,"difficulty":25,"q":26,"a":27},"what-is-mixin","medium","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":29,"difficulty":25,"q":30,"a":31},"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":33,"difficulty":14,"q":34,"a":35},"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":37,"difficulty":25,"q":38,"a":39},"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":41,"difficulty":25,"q":42,"a":43},"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":45,"difficulty":25,"q":46,"a":47},"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":49,"difficulty":25,"q":50,"a":51},"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":53,"difficulty":14,"q":54,"a":55},"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":57,"difficulty":14,"q":58,"a":59},"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":61,"difficulty":25,"q":62,"a":63},"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":65,"difficulty":14,"q":66,"a":67},"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":69,"difficulty":25,"q":70,"a":71},"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":73,"difficulty":14,"q":74,"a":75},"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":77,"difficulty":25,"q":78,"a":79},"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":81,"difficulty":25,"q":82,"a":83},"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":85,"difficulty":25,"q":86,"a":87},"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":89,"difficulty":25,"q":90,"a":91},"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":93,"difficulty":25,"q":94,"a":95},"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":97,"difficulty":14,"q":98,"a":99},"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":101,"difficulty":14,"q":102,"a":103},"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":105,"difficulty":25,"q":106,"a":107},"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":109,"difficulty":14,"q":110,"a":111},"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":113,"difficulty":25,"q":114,"a":115},"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",null,{"description":11},"JavaScript mixins and composition interview questions — sharing behavior without inheritance, mixin factories, composition over inheritance, and duck typing.","javascript\u002Fclasses\u002Fmixins-composition","Mixins & Composition","Classes & OOP","classes","2026-06-18","aHIXUIyhSVDUwHvZ-v5yI9JeKd24BUHXfIhRZezvWQU",[126,130,133,137],{"subtopic":127,"path":128,"order":129},"Class Syntax & Methods","\u002Fjavascript\u002Fclasses\u002Fclass-syntax",1,{"subtopic":131,"path":132,"order":12},"Inheritance with extends & super","\u002Fjavascript\u002Fclasses\u002Fclass-inheritance",{"subtopic":134,"path":135,"order":136},"Static & Private Members","\u002Fjavascript\u002Fclasses\u002Fstatic-private",3,{"subtopic":120,"path":21,"order":20},{"path":139,"title":140},"\u002Fblog\u002Fjavascript-mixins-composition-explained","JavaScript Mixins & Composition — Sharing Behavior Beyond Single Inheritance",1781808676314]