Skip to main content

Adding methods after an object is created

Yes, you can. JavaScript objects are dynamic: assign a new property whose value is a function, and it immediately becomes a fully fledged method.

Theory

TL;DR

  • A method is an ordinary property whose value happens to be a function, so it can be added at any time.
  • The shortest form is obj.method = function () { ... }.
  • Several methods at once are convenient with a single Object.assign(obj, { ... }) call.
  • To give the method to every instance, put it on the prototype: User.prototype.method = ....
  • Use regular functions for methods: arrow functions have no this of their own.

Quick example

javascript
const user = { name: 'Maria' }; // adding a method after creation user.sayHi = function () { console.log(`Hello, ${this.name}!`); }; user.sayHi(); // "Hello, Maria!"

The sayHi method appeared after the object was declared, and it is now a normal method of that object.

Plain assignment of a function

Direct assignment is the most common way. You can add as many methods as you like, whenever you like:

javascript
const calculator = {}; calculator.add = function (a, b) { return a + b; }; calculator.multiply = function (a, b) { return a * b; }; console.log(calculator.add(2, 3)); // 5 console.log(calculator.multiply(2, 3)); // 6

Bracket notation works too when the method name is computed: obj['say' + 'Hi'] = function () {}.

Arrow functions: possible, but be careful

javascript
user.sayBye = () => { console.log(`Bye, ${user.name}!`); }; user.sayBye(); // "Bye, Maria!"

The difference:

  • function () has its own this, which points at the object itself when called as user.sayHi();
  • an arrow function => has no own this, so inside it this does not refer to the object but is taken from the enclosing scope.

That is exactly why the example above had to reach for the outer user.name variable instead of this.name. Methods are normally written as regular functions, not arrow ones.

Several methods at once with Object.assign()

javascript
const user = { name: 'Maria' }; Object.assign(user, { sayHi() { console.log(`Hello, ${this.name}`); }, sayBye() { console.log(`Bye, ${this.name}`); } }); user.sayHi(); // "Hello, Maria" user.sayBye(); // "Bye, Maria"

This is handy when you need to add a group of methods at once, or to mix a ready-made set of behaviour into an object (a mixin).

A method on the prototype, that is, for every instance

javascript
function User(name) { this.name = name; } User.prototype.sayHi = function () { console.log(`Hello, ${this.name}`); }; const maria = new User('Maria'); const oleh = new User('Oleh'); maria.sayHi(); // "Hello, Maria" oleh.sayHi(); // "Hello, Oleh"

This adds the method to every instance created with new User(), including the ones that already existed when it was added: the lookup walks the prototype chain at call time. The function is also stored once in memory rather than copied into each object.

Summary table

WayWhen to use itExample
obj.method = function () {}add a single methoduser.sayHi = ...
Object.assign(obj, { ... })add several methodsObject.assign(user, { sayHi, sayBye })
prototype.method = ...add a method to all instancesUser.prototype.sayHi = ...

In one sentence: in JavaScript you can add methods to an object at any time, just assign a function to it and it becomes a method:

javascript
obj.newMethod = function () { ... };

Common mistakes

  • Using an arrow function as a method. It has no this of its own, so this.name is undefined or resolves against the outer context.
  • Losing this when the method is passed around. setTimeout(user.sayHi, 100) calls the function with no object. Use user.sayHi.bind(user) or a wrapper such as () => user.sayHi().
  • Bolting methods onto built-in prototypes. Extending Array.prototype or Object.prototype breaks other people's code and pollutes for...in loops.
  • Adding a method to a frozen object. After Object.freeze(obj) the assignment silently does nothing, and under 'use strict' it throws a TypeError.
  • Overwriting an existing property. Assigning the same name quietly replaces whatever was there, so check the key with Object.hasOwn() first.
  • Assuming a late-added method is somehow different. It is not: it is the same ordinary property holding a function value.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.