[{"data":1,"prerenderedAt":154},["ShallowReactive",2],{"qa-\u002Fjavascript\u002Fclasses\u002Fclass-syntax":3},{"page":4,"siblings":138,"blog":151},{"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":129,"seo":130,"seoDescription":131,"stem":132,"subtopic":133,"topic":134,"topicSlug":135,"updated":136,"__hash__":137},"qa\u002Fjavascript\u002Fclasses\u002Fclass-syntax.md","Class Syntax",{"type":8,"value":9,"toc":10},"minimark",[],{"title":11,"searchDepth":12,"depth":12,"links":13},"",2,[],"medium","md","JavaScript","javascript",{},true,1,"\u002Fjavascript\u002Fclasses\u002Fclass-syntax",[23,28,32,36,40,44,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125],{"id":24,"difficulty":25,"q":26,"a":27},"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":29,"difficulty":14,"q":30,"a":31},"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":33,"difficulty":25,"q":34,"a":35},"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":37,"difficulty":14,"q":38,"a":39},"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":41,"difficulty":14,"q":42,"a":43},"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":45,"difficulty":46,"q":47,"a":48},"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":50,"difficulty":14,"q":51,"a":52},"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":54,"difficulty":14,"q":55,"a":56},"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":58,"difficulty":25,"q":59,"a":60},"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":62,"difficulty":14,"q":63,"a":64},"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":66,"difficulty":14,"q":67,"a":68},"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":70,"difficulty":14,"q":71,"a":72},"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":74,"difficulty":25,"q":75,"a":76},"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":78,"difficulty":25,"q":79,"a":80},"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":82,"difficulty":14,"q":83,"a":84},"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":86,"difficulty":14,"q":87,"a":88},"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":90,"difficulty":14,"q":91,"a":92},"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":94,"difficulty":46,"q":95,"a":96},"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":98,"difficulty":14,"q":99,"a":100},"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":102,"difficulty":14,"q":103,"a":104},"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":106,"difficulty":46,"q":107,"a":108},"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":110,"difficulty":46,"q":111,"a":112},"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":114,"difficulty":46,"q":115,"a":116},"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":118,"difficulty":25,"q":119,"a":120},"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":122,"difficulty":14,"q":123,"a":124},"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":126,"difficulty":14,"q":127,"a":128},"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":11},"JavaScript class interview questions — class syntax, constructors, methods, fields, classes vs constructor functions, hoisting and common gotchas.","javascript\u002Fclasses\u002Fclass-syntax","Class Syntax & Methods","Classes & OOP","classes","2026-06-18","nrOdp4po-2N3gRIW5xxIV4MrZLoT1Apgk_BkUHFZq_0",[139,140,143,147],{"subtopic":133,"path":21,"order":20},{"subtopic":141,"path":142,"order":12},"Inheritance with extends & super","\u002Fjavascript\u002Fclasses\u002Fclass-inheritance",{"subtopic":144,"path":145,"order":146},"Static & Private Members","\u002Fjavascript\u002Fclasses\u002Fstatic-private",3,{"subtopic":148,"path":149,"order":150},"Mixins & Composition","\u002Fjavascript\u002Fclasses\u002Fmixins-composition",4,{"path":152,"title":153},"\u002Fblog\u002Fjavascript-class-syntax-methods","JavaScript Class Syntax & Methods Explained — Fields, Getters, and the Prototype Truth",1781808675791]