Object methods, "this"
An object usually stands in for something from the real world: a user, an order, a shopping cart. So far you’ve stored facts about that thing as properties.
let user = {
name: "Maya",
age: 30
};
But a real user does more than sit there holding a name and an age. They log in, log out, add an item to a cart, place an order. Those are actions, and in JavaScript an action attached to an object is a function stored as a property.
Method examples
Let’s teach user to greet us. Start with a plain object, then attach a function to a new property:
let user = {
name: "Maya",
age: 30
};
user.sayHi = function() {
alert("Hello!");
};
user.sayHi(); // Hello!
That’s a Function Expression on the right side of the assignment. It builds a function and stores it in user.sayHi, exactly the way you’d store a string or a number. Once it’s there, you call it with parentheses: user.sayHi(). The user can speak.
A function that lives in an object property has a name of its own: a method. So sayHi is a method of user.
You don’t have to define the function inline. A function declared elsewhere works just as well — assign it to the property afterward:
let user = {
// ...
};
// first, declare
function sayHi() {
alert("Hello!");
}
// then add as a method
user.sayHi = sayHi;
user.sayHi(); // Hello!
Notice that the last line has no difference in behavior. Whether the function was born inside the object or bolted on later, calling user.sayHi() runs it the same way.
Method shorthand
Writing sayHi: function() { ... } inside every object gets noisy. Object literals have a shorter form for methods that drops the colon and the function keyword:
// these objects do the same
user = {
sayHi: function() {
alert("Hello");
}
};
// method shorthand looks better, right?
user = {
sayHi() { // same as "sayHi: function(){...}"
alert("Hello");
}
};
You keep the property name, add parentheses and a body, and skip the rest.
The two forms are almost interchangeable, not exactly. The shorthand version sets up a hidden internal link that matters for object inheritance and super — a detail from a later chapter that you can safely ignore for now. For everyday code, reach for the shorthand.
“this” in methods
A method often needs to read the object it belongs to. Inside user.sayHi(), you might want the user’s name to greet them by it.
A method reaches its own object through the this keyword.
The value of this is the object before the dot — the one used to make the call.
let user = {
name: "Maya",
age: 30,
sayHi() {
// "this" is the "current object"
alert(this.name);
}
};
user.sayHi(); // Maya
While user.sayHi() runs, this holds user, so this.name reads "Maya". Rename the object below and press the button — the same sayHi method greets whatever name it currently finds through this, no rewiring needed.
You could skip this and name the outer variable directly:
let user = {
name: "Maya",
age: 30,
sayHi() {
alert(user.name); // "user" instead of "this"
}
};
It runs, but it’s fragile. The method now hard-codes the variable user. Copy the object to another variable and change what user points at, and the method follows the old name straight off a cliff:
let user = {
name: "Maya",
age: 30,
sayHi() {
alert( user.name ); // leads to an error
}
};
let admin = user;
user = null; // overwrite to make things obvious
admin.sayHi(); // TypeError: Cannot read property 'name' of null
admin and user pointed at the same object. Then user was set to null, but admin still holds the object. Calling admin.sayHi() runs the method — which looks up the variable user, finds null, and tries to read null.name. Crash. Had the method used this.name, this would be admin (the object before the dot), and it would print "Maya" without complaint.
“this” is not bound
Here’s where JavaScript parts ways with languages like Java or C++. In many of them, this inside a method is fixed to the object the method was defined in. In JavaScript it isn’t. this can appear in any function, even one that isn’t a method of anything.
This is not a syntax error:
function sayHi() {
alert( this.name );
}
The function is valid on its own. What this means is decided later, at the moment of the call, based on how the call is made. The same function can serve two different objects and see a different this each time:
let user = { name: "Maya" };
let admin = { name: "Admin" };
function sayHi() {
alert( this.name );
}
// use the same function in two objects
user.f = sayHi;
admin.f = sayHi;
// these calls have different this
// "this" inside the function is the object "before the dot"
user.f(); // Maya (this == user)
admin.f(); // Admin (this == admin)
admin['f'](); // Admin (dot or square brackets access the method – doesn't matter)
One function, three calls, and this shifts to match whatever sits before the dot (or brackets). The rule is short: for a call obj.f(), this inside f is obj.
Try it live. There’s exactly one sayHi function here, borrowed by both objects. Whichever object you put before the dot becomes this:
Arrow functions have no “this”
Arrow functions break the pattern in a useful way. An arrow function has no this of its own. Write this inside one, and it reads the this of the surrounding ordinary function instead.
let user = {
firstName: "Arjun",
sayHi() {
let arrow = () => alert(this.firstName);
arrow();
}
};
user.sayHi(); // Arjun
arrow is called with no object before a dot. If it were a normal function, its this would be undefined and this would throw. Because it’s an arrow, this is borrowed from sayHi, where this is user — so this.firstName is "Arjun".
arrow: () => this.firstName
This is exactly what you want when a small helper should act as part of its enclosing method rather than starting a fresh this of its own. Arrow functions get their own full chapter in Arrow functions revisited.
Both methods below live on the same object and are called the same way. Only the shorthand one sees the object as this; the arrow reaches outside and finds no firstName:
Summary
- A function stored in an object property is a method. Methods let objects act:
object.doSomething(). - Inside a method,
thisrefers to the object the method was called on. - The value of
thisis resolved at run-time, not at declaration:- A function may mention
thiswhen written, but thatthishas no value until the function is called. - The same function can be copied between objects and reused.
- For a call in method form —
object.method()—thisisobject.
- A function may mention
- Arrow functions are the exception: they have no
thisof their own, sothisinside an arrow is taken from the surrounding code.