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.

user
data (properties)
name: “Maya”
age: 30
behavior (methods)
sayHi: ƒ()
Properties hold what an object is; methods hold what it can do.

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.

interactiveA method greets through this
user
.sayHi()
this === user
The object before the dot becomes `this` for the duration of the call.

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:

interactiveOne function, different this each call
user.f()
admin.f()
this → user  ·  “Maya”
this → admin  ·  “Admin”
One function object, reused. Each call binds `this` to its own caller.

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".

sayHi() — this === user

arrow: () => this.firstName

no own this → uses outer this === user

A normal method gets its own `this`; the arrow inside borrows that same `this`.

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:

interactiveShorthand method vs arrow method

Summary

  • A function stored in an object property is a method. Methods let objects act: object.doSomething().
  • Inside a method, this refers to the object the method was called on.
  • The value of this is resolved at run-time, not at declaration:
    • A function may mention this when written, but that this has 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()this is object.
  • Arrow functions are the exception: they have no this of their own, so this inside an arrow is taken from the surrounding code.