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
thisof their own.
Quick example
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:
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)); // 6Bracket notation works too when the method name is computed: obj['say' + 'Hi'] = function () {}.
Arrow functions: possible, but be careful
user.sayBye = () => {
console.log(`Bye, ${user.name}!`);
};
user.sayBye(); // "Bye, Maria!"The difference:
function ()has its ownthis, which points at the object itself when called asuser.sayHi();- an arrow function
=>has no ownthis, so inside itthisdoes 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()
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
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
| Way | When to use it | Example |
|---|---|---|
obj.method = function () {} | add a single method | user.sayHi = ... |
Object.assign(obj, { ... }) | add several methods | Object.assign(user, { sayHi, sayBye }) |
prototype.method = ... | add a method to all instances | User.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:
javascriptobj.newMethod = function () { ... };
Common mistakes
- Using an arrow function as a method. It has no
thisof its own, sothis.nameisundefinedor resolves against the outer context. - Losing
thiswhen the method is passed around.setTimeout(user.sayHi, 100)calls the function with no object. Useuser.sayHi.bind(user)or a wrapper such as() => user.sayHi(). - Bolting methods onto built-in prototypes. Extending
Array.prototypeorObject.prototypebreaks other people's code and pollutesfor...inloops. - Adding a method to a frozen object. After
Object.freeze(obj)the assignment silently does nothing, and under'use strict'it throws aTypeError. - 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 readyA concise answer to help you respond confidently on this topic during an interview.