search ]

JavaScript Object Methods and ‘this’ Explained for Beginners

In JavaScript, objects are used to group related data and functions. These functions that belong to an object are known as methods.

One important aspect of methods in JavaScript is the usage of the this keyword, which often confuses beginners. This guide will help you understand how methods work and how this behaves in different contexts.

Object methods allow you to organize your code around real-world entities. The this keyword dynamically refers to the object that is calling the method.

1. Creating Object Methods

You can define a method inside an object by assigning a function to a property:

const user = {
  name: "Alice",
  greet: function() {
    console.log("Hello, " + this.name + "!");
  }
};

user.greet(); // Output: Hello, Alice!

In the example above, greet() is a method of the user object. It uses this.name to access the name property of the object.

2. Method Shorthand Syntax

JavaScript allows a shorter way to define methods inside objects. Instead of writing greet: function() {}, you can simply write greet() {}:

const user = {
  name: "Bob",
  greet() {
    console.log("Hello, " + this.name + "!");
  }
};

user.greet(); // Output: Hello, Bob!

This shorthand syntax was introduced in ES6 and is the preferred way to define object methods in modern JavaScript.

3. What is this?

The keyword this refers to the object that is currently executing the function. When a method is called with dot notation, this refers to the object before the dot.

const car = {
  brand: "Toyota",
  start() {
    console.log(this.brand + " engine started.");
  }
};

car.start(); // Output: Toyota engine started.

Remember: The value of this depends on how the function is called, not where it is defined.

4. Losing this Context

When a method is assigned to a variable or passed as a callback, it can lose its original context. This is one of the most common pitfalls beginners encounter.

const person = {
  name: "Dana",
  speak() {
    console.log(this.name);
  }
};

const sayName = person.speak;
sayName(); // Output: undefined (or error in strict mode)

When you assign person.speak to sayName, the function is no longer called as a method of person. It becomes a standalone function, so this no longer refers to the person object.

To fix this, you can use bind() to permanently bind this to the original object:

const boundSpeak = person.speak.bind(person);
boundSpeak(); // Output: Dana

5. Arrow Functions and this

Arrow functions do not have their own this. Instead, they inherit this from their surrounding (lexical) scope.

This makes arrow functions useful inside callbacks, but problematic when used as object methods:

const dog = {
  name: "Rex",
  bark: () => {
    console.log(this.name); // 'this' does not refer to 'dog'
  }
};

dog.bark(); // Output: undefined

Use regular functions (or the shorthand syntax) for object methods when you need to access this. Arrow functions are best suited for callbacks and closures where you want to preserve the outer this context.

6. Using call(), apply(), and bind()

JavaScript provides three built-in methods that let you explicitly control the value of this when calling a function.

call() invokes the function immediately and accepts arguments one by one:

function greet(greeting) {
  console.log(greeting + ", " + this.name);
}

const user = { name: "Alice" };
greet.call(user, "Hello"); // Output: Hello, Alice

apply() works the same way, but accepts arguments as an array:

greet.apply(user, ["Hi"]); // Output: Hi, Alice

bind() does not call the function immediately. Instead, it returns a new function with this permanently set:

const greetAlice = greet.bind(user, "Hey");
greetAlice(); // Output: Hey, Alice

Here is a quick comparison:

MethodInvokes immediately?Arguments format
call()YesComma-separated
apply()YesArray
bind()No (returns new function)Comma-separated

7. this in Constructor Functions and Classes

When you use the new keyword with a constructor function or a class, this refers to the newly created object.

function Person(name) {
  this.name = name;
  this.greet = function() {
    console.log("Hi, I'm " + this.name);
  };
}

const alice = new Person("Alice");
alice.greet(); // Output: Hi, I'm Alice

The same applies to ES6 classes:

class Animal {
  constructor(name) {
    this.name = name;
  }
  speak() {
    console.log(this.name + " makes a sound.");
  }
}

const cat = new Animal("Whiskers");
cat.speak(); // Output: Whiskers makes a sound.

In both cases, this inside the constructor or method refers to the specific instance that was created.

8. this in Event Handlers

When you use a regular function as a DOM event handler, this refers to the HTML element that received the event:

document.querySelector("button").addEventListener("click", function() {
  console.log(this); // the button element
  this.style.backgroundColor = "red";
});

However, if you use an arrow function as the handler, this will refer to the surrounding scope (usually window), not the element:

document.querySelector("button").addEventListener("click", () => {
  console.log(this); // window, not the button
});

Use regular functions for event handlers when you need this to reference the DOM element.

9. Visual Summary Table

ContextValue of this
Object methodThe object
Function (strict mode)undefined
Function (non-strict)Global object (window)
Arrow functionLexical (surrounding) scope
Constructor / classThe new instance
Event handler (regular function)The DOM element
call() / apply() / bind()Explicitly set value

10. Common Pitfalls

  • Using arrow functions for methods and expecting this to refer to the object.
  • Detaching methods from objects (e.g., assigning to a variable) and losing their context.
  • Assuming this always refers to the object where the function was defined.
  • Forgetting that setTimeout and setInterval callbacks lose this context – wrap them in an arrow function or use bind() to fix it.

11. Practical Use Case: To-Do Item

Here is a more realistic example using a to-do item object:

const todo = {
  title: "Learn JavaScript",
  done: false,
  markDone() {
    this.done = true;
    console.log(`"${this.title}" marked as done.`);
  }
};

todo.markDone(); // Output: "Learn JavaScript" marked as done.

12. Try It in the Console

To better understand this, open your browser’s developer tools (F12), go to the Console tab, and paste any of the code examples.

You may notice that after executing a function like user.greet(), the console outputs the expected message followed by undefined. This happens because the method does not explicitly return a value – the console displays the return value of the last executed expression, and in this case, it is undefined. This is normal and not an error.

Code Example in Google Chrome Console

13. Using Strict Mode

Enabling strict mode changes the default behavior of this in standalone functions. In non-strict mode, this defaults to the global object (window in browsers). In strict mode, this will be undefined instead.

"use strict";
function testThis() {
  console.log(this); // undefined
}
testThis();

It is considered best practice to always use strict mode (or ES modules, which are strict by default). This helps catch bugs where this accidentally refers to the global object instead of being undefined.

Real-World Example: User Management

Here is how object methods and this can be used in a simple user system:

const user = {
  username: "admin",
  login() {
    console.log(this.username + " has logged in.");
  },
  logout() {
    console.log(this.username + " has logged out.");
  }
};

user.login();  // admin has logged in.
user.logout(); // admin has logged out.

This example shows how methods can represent actions and how this refers to the object that calls them.

FAQs

Common questions about JavaScript object methods and this:

What does this refer to inside a JavaScript object method?
When a function is called as a method of an object (using dot notation, like obj.method()), this refers to the object before the dot. For example, in user.greet(), this inside greet refers to the user object.
Why does this become undefined when I assign a method to a variable?
When you assign a method to a variable (e.g., const fn = obj.method), the function loses its connection to the object. Calling fn() is a standalone function call, so this defaults to the global object (or undefined in strict mode). Use bind() to permanently attach the correct this value.
Can I use an arrow function as an object method?
You can, but it usually will not work as expected. Arrow functions do not have their own this - they inherit it from the surrounding scope. If the surrounding scope is the global scope, this will be window (or undefined in strict mode), not the object. Use regular functions or the shorthand method syntax for object methods.
What is the difference between call(), apply(), and bind()?
call() and apply() both invoke the function immediately with a specified this value. The difference is that call() takes arguments individually, while apply() takes them as an array. bind() does not invoke the function - it returns a new function with this permanently set, which you can call later.
How does this work inside a class or constructor function?
When you create an instance with the new keyword, this inside the constructor (or class constructor) refers to the newly created object. Each instance gets its own this, so properties set with this.name = value are unique to that instance.

Conclusion

Understanding object methods and the this keyword is essential for mastering JavaScript. The key takeaway is that this is determined by how a function is called, not where it is defined.

Use regular functions for object methods, arrow functions for callbacks, and bind(), call(), or apply() when you need explicit control. Keep experimenting with different calling contexts to see how this behaves – it will become second nature with practice.

Join the Discussion
0 Comments  ]

Leave a Comment

To add code, use the buttons below. For instance, click the PHP button to insert PHP code within the shortcode. If you notice any typos, please let us know!

Savvy WordPress Development official logo