Suggest an editImprove this articleRefine the answer for “How to add a method to a class”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)**You add a method right in the class body with `name() {}`, and it automatically lands on `Class.prototype`, which makes it shared by every instance.** Besides the ordinary method there are four more options: `static name() {}` for a method of the class itself, the `get name() {}` / `set name(v) {}` pair for access that looks like a property, `#name() {}` for a genuinely private method, and an arrow field `name = () => {}` that binds `this` to the instance. You can also attach a method after the class declaration with `Class.prototype.name = function () {}`, because under the hood a `class` is a function with a prototype. **Key point:** ordinary methods live on the prototype and are shared by all objects, while arrow fields are recreated per instance but never lose `this`.Shown above the full answer for quick recall.Answer (EN)Image**You add a method to a class by simply writing it in the class body: `greet() { ... }`, after which it lands on the prototype and becomes available to every instance.** Besides the ordinary method, JavaScript gives you static methods, getters and setters, private methods with `#`, and method fields holding an arrow function, and each variant solves its own problem. ## Theory ### TL;DR - An ordinary method `m() {}` in the class body lands on `Class.prototype` and is shared by all instances. - A method can also be attached after the declaration: `Class.prototype.m = function () {}`. - `static m() {}` belongs to the class itself, instances do not see it. - `get` and `set` provide access that looks like a plain property. - `#m() {}` is a genuinely private method, reachable only from inside the class. - An arrow field `m = () => {}` never loses `this`, which makes it handy for callbacks. ### Quick example ```javascript class User { constructor(name) { this.name = name; } greet() { console.log(`Hi, ${this.name}!`); } } const u = new User("Alice"); u.greet(); // Hi, Alice! ``` ### Ordinary method, and adding a method later An ordinary (public) method is available on every instance of the class: ```javascript class User { constructor(name) { this.name = name; } greet() { console.log(`Hi, ${this.name}!`); } } const u = new User("Alice"); u.greet(); // Hi, Alice! ``` Such methods are automatically added to `User.prototype`, which means they are shared by all instances instead of being recreated for every object. A method can also be put on the class prototype after the declaration, by hand: ```javascript class User { constructor(name) { this.name = name; } } // Adding the method later User.prototype.sayBye = function () { console.log(`${this.name} says: bye!`); }; const u = new User("Alice"); u.sayBye(); // Alice says: bye! ``` This works because under the hood a `class` is just a function with a `prototype`. One detail differs: a manually added method is enumerable, while methods from the class body are not. ### Static method Such a method is called directly on the class, not on an instance: ```javascript class MathUtils { static square(n) { return n * n; } } console.log(MathUtils.square(5)); // 25 ``` > Instances (`new MathUtils()`) have no access to `static` methods. ### Getter and setter They are used to "disguise" properties as methods and to control access to them: ```javascript class Product { constructor(price) { this._price = price; } get price() { return this._price + " USD"; } set price(value) { if (value < 0) throw new Error("Price cannot be negative"); this._price = value; } } const p = new Product(1000); console.log(p.price); // "1000 USD" p.price = 1500; console.log(p.price); // "1500 USD" ``` > Reading `p.price` actually calls `get price()`, and assigning `p.price = ...` calls `set price()`. ### Private methods and arrow method fields Private methods with a hash are unreachable from outside, only from inside the class: ```javascript class Account { #logBalance() { console.log(`Current balance: ${this.balance}`); } constructor(balance) { this.balance = balance; this.#logBalance(); // can only be called from here } } const acc = new Account(500); // acc.#logBalance(); -> error, this is a private method ``` If you need a method to keep its `this` context, declare it as a field holding an arrow function: ```javascript class Button { label = "Click me"; handleClick = () => { console.log(`Clicked: ${this.label}`); }; } const b = new Button(); b.handleClick(); // Clicked: Click me ``` Such methods do not lose `this` even when passed around as a callback: ```javascript setTimeout(b.handleClick, 1000); // everything works correctly ``` The price for that: an arrow field is created separately for every instance and does not live on the prototype. ### Summary table | Method kind | Syntax | Accessibility | Notes | | --- | --- | --- | --- | | Ordinary | `method() {}` | Through an instance | Shared by all instances | | Static | `static method() {}` | Through the class itself | Not visible on instances | | Getter / setter | `get name() {}`, `set name(v) {}` | Like a property | Lets you control access | | Private | `#method() {}` | Only inside the class | Full encapsulation | | Method field (arrow) | `method = () => {}` | Through an instance | Does not lose `this` | ### Common mistakes - Putting a comma or a semicolon between methods in the class body: this is not an object literal, no separators are needed there. - Making every method an arrow field "so you never think about `this`": that gives each instance its own copies of the functions and throws away the prototype benefit. - Calling a `static` method on an instance and getting a `TypeError`. - Naming a getter exactly like a field (`get price()` plus `this.price = ...` in the constructor): that gives infinite recursion, which is why the example names the field `_price`. - Forgetting that `#` methods are invisible even in subclasses: class privacy works per class, not along the prototype chain.For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.