completefrontend
Open lab My progress
THE JAVASCRIPT FIELD GUIDE

Methods & this

Learn how functions stored on objects become methods, how this is chosen by the call shape, and how returning this powers method chaining.

By the end, you can
  • 01
    Write method shorthandStore a function on an object with greet() {}, and read other properties of that object with this.
  • 02
    Predict thisFind the object before the dot to say what this is in obj.method(), and spot a call that loses this.
  • 03
    Build chainsReturn this from methods that change the object, so several calls can follow one another in one line.

Methods are functions that belong to objects

In Object basics, objects held data, such as names, scores, and settings. Each piece of data sits in a property: a name with a value. A property can also hold a function. A function stored in an object property is called a method.

A function stored on an objectPop out in the code editor (opens in a new tab)JavaScript
const dog = {  name: "Pixel",  bark: function () {    return this.name + " says woof";  },}; console.log(dog.bark()); // Pixel says woof

Line 3 stores a function in the property bark. Line 4 uses this.name. It reads the name of the object that called the method. Line 8 calls the method through dog. So this is dog, and the program prints Pixel says woof.

Why not write dog.name on line 4? Because one function can be shared by many objects. dog.name would always read the dog's name, even when another object calls the function. The special word this means "the object this method is working on right now".

One function, two objectsPop out in the code editor (opens in a new tab)JavaScript
function greet() {  return "Hi " + this.name;} const asha = { name: "Asha", greet };const rae = { name: "Rae", greet }; console.log(asha.greet());console.log(rae.greet());

Line 1 makes one plain function, greet. Line 2 doesn't name Asha or Rae. Lines 5 and 6 store that one function on two objects. Writing greet alone inside the braces is short for greet: greet.

Line 8 calls the function through asha, so it prints Hi Asha. Line 9 calls it through rae, so it prints Hi Rae.

Left: asha.greet(). The greet card is in the asha cart, so this is asha. Right: rae.greet(). The same greet card is in the rae cart, so this is rae.asha.greet()greet()ashathis = asharae.greet()greet()raethis = rae
Both objects hold the same greet function. The object before the dot becomes this, so the same function greets Asha in one call and Rae in the other.
A method can change data on its own objectPop out in the code editor (opens in a new tab)JavaScript
const cart = {  items: 0,  addTea() {    this.items = this.items + 1;    return this.items;  },}; console.log(cart.addTea());

Line 4 adds 1 to items on the cart that made the call. Line 9 calls the method through cart, so it prints 1. This is a common job for a method. The object keeps its data and the action that changes that data in one place.

Real-life analogyA method is a skill a character has

Think of an object as a character card in a game. The card lists facts, like a name. It also lists skills, like bark. A method is one of those skills. When Pixel uses a skill, the word "my" means Pixel.

In real life: Pixel has the skill bark
In JavaScript: dog.bark holds a function
In real life: The skill can use Pixel’s name
In JavaScript: The method reads this.name
In real life: Another dog can have the same skill
In JavaScript: The same function can be called as nori.bark()

This lesson teaches one main rule. When you call a method as object.method(), this is the object before the dot. JavaScript chooses it at the moment of the call.

There are more rules for this, and Stage 4 has a full module on them. It covers call, apply, and bind, which set this by hand, plus what this is outside any object and more strict-mode details.

Method shorthand

STEP THROUGH

Most methods are written in a shorter way, called method shorthand. Instead of bark: function () { ... }, you write bark() { ... }. For everyday calls, both work the same. Both store a regular function in the bark property.

There is one small difference for later. You can't use a shorthand method with new. You'll meet new in the next lesson, Constructors & new.

The same method, written two waysPop out in the code editor (opens in a new tab)JavaScript
const oldStyle = {  name: "Ada",  greet: function () {    return "Hi " + this.name;  },}; const shorthand = {  name: "Ada",  greet() {    return "Hi " + this.name;  },};

Line 3 is the old style. Line 10 is the shorthand. The shorter spelling is not the important part. The important part is how the method reads data from its object. In both, this.name means "the name property of the object using this method right now".

A shorthand method in a full programPop out in the code editor (opens in a new tab)JavaScript
const user = {  name: "Asha",  greet() {    return "Hi " + this.name;  },}; console.log(user.greet());

Line 3 makes a method named greet. Line 4 reads the name of the object that called it. Line 8 calls it through user, so it prints Hi Asha. Use a shorthand method when an action needs other properties of the same object.

  • A method can return a value, change its object, or do both.
  • Use a regular method when it reads this.name, this.total, or another property of the same object.
  • If a helper needs no data from an object, a plain function is usually clearer.
Step through method shorthand
Step 0 of 4Ready
Your turn: follow the blue line

Predict what dog.bark() prints. Then step through to see how method shorthand and this work together.

Running in
  1. script
Next: line 1
  name: "Pixel",  bark() {    return this.name + " says woof";  },}; console.log(dog.bark());
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
A method is still a value

A method is a function value stored in a property. The function doesn't stay tied to that object forever. That's why the next section looks at how the function is called, not where it was written.

this is decided at call time

INTERACTIVE

Here is the rule to practice: look at the call itself. In ada.introduce(), the object before the dot is ada, so this is ada. In lin.introduce(), the object before the dot is lin. So the same function gets a different this.

Who is this? Change the last line
Step 0 of 6Ready
Your turn: follow the blue line

Choose the last line, then step through to see the same function get a different this.

Running in
  1. script
Next: line 2
"use strict";  return "Hi, I am " + this.name;} const ada = { name: "Ada", introduce };const lin = { name: "Lin", introduce }; ada.introduce();
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
Choose the last line, then predict this.name

Changing the last line starts the replay again. Watch the same function get a different this.

A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

Now try the third choice, "Saved copy". Line 9 saves the function in a new variable, speak. Line 10 calls speak(). That call has no dot, so there is no object before a dot.

The code starts with "use strict". That line turns on strict mode, a stricter set of JavaScript rules. Code in JavaScript modules, like the code on this site, always runs in strict mode. In strict mode, a call with no object gives this the value undefined. Reading this.name then throws a TypeError: the error JavaScript throws when you use a value in a way it can't be used.

Left: ada.introduce(). The introduce card is in the ada cart, so this is ada. Right: speak(). The same introduce card is alone in a box called speak, so this is undefined.ada.introduce()introduce()adathis = adaspeak()introduce()speakthis = undefined
The same function in both. Called as ada.introduce(), it works on Ada. Saved in its own variable and called as speak(), it has no object to work on.
Real-life analogythis is like “me” or “my”

The word "my" changes meaning with the speaker. If Ada says "my laptop", it is Ada's laptop. If Lin says the same words, it is Lin's laptop. this works the same way in a method call. Its meaning comes from the object that makes the call right now.

In real life: Ada says “my name”
In JavaScript: ada.introduce() makes this be ada
In real life: Lin says “my name”
In JavaScript: lin.introduce() makes this be lin
In real life: A note says “my name” but nobody signed it
In JavaScript: speak() has no object before the dot
With two dots, the last one countsPop out in the code editor (opens in a new tab)JavaScript
const app = {  user: {    name: "Lin",    introduce() {      return "Hi " + this.name;    },  },}; console.log(app.user.introduce());

The call on line 10 is app.user.introduce(). It has two dots. The object right before introduce is app.user, not the outer app. So this is app.user, and line 10 prints Hi Lin.

Arrow functions, callbacks, and losing this

SORT

You met arrow functions, like () => 1, in the Arrow functions lesson. An arrow function has no this of its own. Inside an arrow, this means whatever this meant in the code around it. That helps in one place and hurts in another:

  • Helpful: an arrow inside a method keeps the method's this.
  • Not helpful: an arrow used as the method doesn't get the object as this when you call object.method().

The table below compares four ways to put a function on an object. Read each row as: "if I write this, is this the object, and when should I use it?"

Regular methods and arrow functions on an object
When you writeIs this the object?When to use it
greet() { return this.name; }Yes, when you call obj.greet().For a method that reads or changes other properties of the same object.
greet: function () { return this.name; }Yes, when you call obj.greet().This is the older way to write the same method.
greet: () => this.nameNo. The arrow keeps the this from outside the object.Almost never. Don't use an arrow as a method that needs this.
() => obj.greet()The arrow has no this of its own. But it runs the real call obj.greet(), so greet gets obj.As a wrapper when you pass a method to other code.
A regular method and an arrow methodPop out in the code editor (opens in a new tab)JavaScript
const user = {  name: "Mina",  regular() {    return this.name;  },  arrow: () => this.name,}; console.log(user.regular());console.log(user.arrow());

Line 3 is a regular method, so line 9 calls it with user as this and prints Mina. Line 6 is an arrow. It doesn't get user as this. It uses the this from the code outside the object, which has no name. In this example, line 10 prints undefined.

An arrow inside a method keeps thisPop out in the code editor (opens in a new tab)JavaScript
const team = {  prefix: "Team",  names: ["Ada", "Lin"],  labels() {    return this.names.map((name) => this.prefix + ": " + name);  },}; console.log(team.labels().join(", "));

Line 4 makes a regular method, labels(). Line 5 uses map. map runs a function once for each item in an array and collects the results in a new array.

The function given to map is an arrow. The arrow has no this of its own, so it uses the this of labels(), which is team. Line 9 joins the results with join(", ") and prints Team: Ada, Team: Lin. The arrow is inside the method; it is not the method itself.

Callbacks are the other common way to lose this. A callback is a function you give to other code, so that code can call it later. For example, setTimeout(fn, 1000) calls fn after 1000 milliseconds, which is one second.

If you pass timer.announce to setTimeout, you pass only the function. Later, setTimeout calls that function on its own, not as timer.announce(). So the function no longer gets timer as this. A simple fix is an arrow wrapper: () => timer.announce(). In Stage 4 you'll also learn bind, another fix.

A wrapper makes the method call laterPop out in the code editor (opens in a new tab)JavaScript
const timer = {  label: "tea is ready",  announce() {    return this.label;  },}; const later = () => timer.announce();console.log(later());

Line 8 makes a new function, later. It doesn't run announce yet. When line 9 calls later(), the arrow runs timer.announce(). That call has timer before the dot, so this is timer, and line 9 prints tea is ready. Use a wrapper like this for clicks, timers, and other callbacks that run a method later.

Left: setTimeout(timer.announce). Only the announce card goes into the callback box, so the timer is lost. Right: an arrow wrapper. The box called later holds the whole call, timer.announce(), so this is timer.setTimeout(timer.announce)announce()callbacktimer is lost() => timer.announce()timer.announce()laterthis = timer
Passing timer.announce hands over only the function. The timer is left behind. The wrapper () => timer.announce() keeps the whole call, dot included, and runs it later.
Where does this point?
  • dog.bark()
  • app.user.sayName()
  • const fn = dog.bark; fn()
  • setTimeout(dog.bark, 0)
  • setTimeout(() => dog.bark(), 0)
  • const dog = { bark: () => this.name }
Try it yourself
0 of 6 correct

Sort each call by what happens to this. Look at the object before the last dot.

Choose a category for every card. You can change an answer at any time; Reset clears them all.

Method chaining

INTERACTIVE

Method chaining means calling several methods in one line, one after another, like counter.add(2).add(3).double().read().

It works because each method that changes the object ends with return this. What it returns is the same counter. So the next dot has an object to call a method on.

The chain counter.add(2).add(3).read(). add(2) returns this, the counter, to add(3). add(3) returns the counter to read(). read() returns the number 5.counter.add(2).add(3).read()add(2)add(3)read()5return this(counter)return this(counter)return 5
Each arrow is a return value. add(2) and add(3) return this, the same counter, so the next dot has an object to call. read() returns the number 5, so the chain ends there.
Real-life analogyA chain is an assembly line

In a factory, an assembly line is a row of work stations. Each station works on the same product, then passes it to the next station. If one station forgets to pass it on, the next station has nothing to work on. A chained method that forgets return this causes the same problem.

In real life: Station 1 adds a part and passes the product on
In JavaScript: add(2) changes the object and returns this
In real life: Station 2 works on the same product
In JavaScript: .add(3) gets the same object
In real life: The last station reports the result
In JavaScript: .read() returns the final value
Step through a method chain
Step 0 of 8Ready
Your turn: follow the blue line

Step through a chain. Watch each method that changes the counter return this, so the next method has an object to call.

Running in
  1. script
Next: line 1
  value: 0,  add(amount) {    this.value = this.value + amount;    return this;  },  double() {    this.value = this.value * 2;    return this;  },  read() {    return this.value;  },}; counter.add(2).add(3).double().read();
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
Returning this returns the same objectPop out in the code editor (opens in a new tab)JavaScript
const cart = {  total: 0,  add(price) {    this.total = this.total + price;    return this;  },}; const sameCart = cart.add(3);console.log(sameCart === cart);console.log(cart.total);

Line 5 returns the cart itself, not a copy. Line 9 saves what cart.add(3) returned in sameCart. Line 10 uses === to check whether sameCart and cart are the very same object. It prints true.

The method also changed the cart's total, so line 11 prints 3. So a chain usually changes the original object.

A read method ends the chain with a valuePop out in the code editor (opens in a new tab)JavaScript
const counter = {  value: 1,  add() {    this.value = this.value + 1;    return this;  },  read() {    return this.value;  },}; console.log(counter.add().read());

Line 5 keeps the chain going: it returns the counter. Line 8 is different: read() returns a number, not the counter. The value starts at 1, and one add() makes it 2. So line 12 prints 2. End a chain with a method like this when you need the final value, for example to show it on the page.

Build a counter chain
A counter whose methods can chainPop out in the code editor (opens in a new tab)JavaScript
const counter = {  value: 0,  add(amount) {    this.value = this.value + amount;    return this;  },  double() {    this.value = this.value * 2;    return this;  },  read() {    return this.value;  },}; counter.add(2).add(3).double().read();
The chain so far0 calls

counter

counter.value0
resultnot run yet

The error you get when a method forgets to return this: TypeError: Cannot read properties of undefined (reading 'double')

Try it yourself

Build a chain one method at a time. Start with add(2), then try double(), then break the chain with brokenAdd(2).

Each button adds one real method call to the end of the chain. brokenAdd(2) adds 2 but forgets return this. Reset starts again with a new counter at 0.
When not to chain

Chain only when each call continues the same simple task. Don't pack complicated decisions into one long line. A few clear lines are better than one clever chain.

Where you’ll use this

You'll use methods wherever an object has both data and actions. For example:

  • a form checker that tests what a user typed
  • a shopping cart that adds items and adds up the total
  • a counter, or a tool that formats dates
  • a small object that remembers the state of one part of a page

The object keeps related values together. Its methods are the actions that make sense for those values.

A small text builder that chainsPop out in the code editor (opens in a new tab)JavaScript
const headline = {  text: "",  word(value) {    this.text = this.text + value + " ";    return this;  },  shout() {    this.text = this.text.toUpperCase();    return this;  },  read() {    return this.text.trim();  },}; console.log(headline.word("methods").word("click").shout().read());

Line 16 reads like a sentence: add a word, add another word, shout, then read. On line 8, toUpperCase() turns the text into capital letters. On line 12, trim() removes the extra space at the end. The program prints METHODS CLICK.

It works because of the same small rule. Each method that changes the text uses this for the current object. Then it returns this for the next call.

  • Use a method when an action belongs with one object's data, such as cart.add(price).
  • Let a read method such as read() only return a value. It shouldn't also change the object.
  • To update a page, call one named method, such as profile.rename(name). Don't change the same properties from many places in your code.
  • Don't make a method just to hold a calculation that doesn't use the object. A plain function is easier to test and reuse.

Common misconceptions

“A method always knows its object.”

No. You can copy a function into another variable or object. this is chosen by how you call the function, not by where it was first stored.

“this means the object where the function was written.”

No. The same function can be stored on two objects. ada.introduce() gets ada as this, and lin.introduce() gets lin.

“Arrow functions are just shorter methods.”

They are shorter, but they have no this of their own. Use a regular method when it reads or changes the object's properties.

“Callbacks keep their object.”

No. Passing user.say on its own passes only the function. Wrap it as () => user.say(), or use bind, which you'll learn in Stage 4.

“Every method should return this.”

Only methods meant to continue a chain should return this. A method such as read() should return the value you need.

Coming next: constructors

Constructors use this too, but with a different kind of call: new Something(). That's the next lesson, Constructors & new.

Practice: methods and this

6 EXERCISES
Exercise 1 · Warm-upAdd a method that reads this

Add a describe method to the book object. It should print the exact sentence the answer box expects.

Starter codePop out in the code editor (opens in a new tab)JavaScript
const book = {
  title: "Eloquent JavaScript",
  describe() {
    return this.title + " is on the shelf";
  },
};
console.log(book.describe());

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · PracticePredict two callers

    Predict both printed lines before you run the code.

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    "use strict";
    function label() {
      return this.name;
    }
    const first = { name: "first", label };
    const second = { name: "second", label };
    console.log(first.label());
    console.log(second.label());

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeFix a callback that loses this

      Imagine some other code will call callback() later. Make the callback print break time.

      Starter codePop out in the code editor (opens in a new tab)JavaScript
      const timer = {
        label: "break time",
        announce() {
          console.log(this.label);
        },
      };
      const callback = () => timer.announce();
      callback();

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeMake methods chainable

        Build a small object whose word method can be called twice in one chain.

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        const list = {
          text: "",
          word(value) {
            this.text = this.text + value;
            return this;
          },
          read() {
            return this.text;
          },
        };
        console.log(list.word("go").word("!").read());

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeUpdate a shopping cart

          A checkout page adds a tea for 3 and a snack for 2. Finish the cart methods so one chain prints 5. Many small cart, filter, and builder tools work this way.

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          const cart = {
            total: 0,
            add(price) {
              this.total = this.total + price;
              return this;
            },
            readTotal() {
              return this.total;
            },
          };
          console.log(cart.add(3).add(2).readTotal());

          Answer, then press Check. Spacing and letter case don’t matter.

            Exercise 6 · ChallengeFix an arrow method

            Rewrite the greeting as a regular method, so this.name reads the object's name.

            Starter codePop out in the code editor (opens in a new tab)JavaScript
            const user = {
              name: "Rae",
              greet() {
                return "Hi " + this.name;
              },
            };
            console.log(user.greet());

            Answer, then press Check. Spacing and letter case don’t matter.

              Quiz: check your understanding

              7 QUESTIONS

              Each choice comes with a short explanation. For code questions, find the object before the dot first.

              Lesson quiz · 7 questionsScore: first tries count
              1. Question 1 of 7Which object is this inside cat.meow()?

                Choose an answer to see the explanation.

              2. Question 2 of 7What does this pet method print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                const pet = {
                  name: "Nori",
                  speak() {
                    console.log(this.name);
                  },
                };
                pet.speak();

                Choose an answer to see the explanation.

              3. Question 3 of 7Which of these is method shorthand?

                Choose an answer to see the explanation.

              4. Question 4 of 7This strict-mode code saves a method in a variable, then calls it on its own. What happens?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                "use strict";
                const user = {
                  name: "Ari",
                  say() {
                    console.log(this.name);
                  },
                };
                const fn = user.say;
                fn();

                Choose an answer to see the explanation.

              5. Question 5 of 7Why does counter.add(2).double() work?

                Choose an answer to see the explanation.

              6. Question 6 of 7What does this counter chain print?

                Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
                const counter = {
                  value: 1,
                  add() {
                    this.value = this.value + 1;
                    return this;
                  },
                  read() {
                    console.log(this.value);
                  },
                };
                counter.add().add().read();

                Choose an answer to see the explanation.

              7. Question 7 of 7Which callback still calls the method on user?

                Choose an answer to see the explanation.

              Key takeaways

              • A method is a function stored in an object property.
              • Method shorthand, greet() { ... }, is the usual way to write a method.
              • In obj.method(), this is obj. JavaScript chooses it when the call happens.
              • A saved copy, or a callback passed on its own, loses the object before the dot. An arrow wrapper, or bind, fixes that.
              • Methods that continue a chain return this. The last method in a chain returns the value you need.

              Remember the one-liner.
              A method is a function stored on an object; this is the object before the dot in that call.

              Up next: Constructors & new.

              CompleteFrontend Clear concepts. Working examples.