What’s the difference between methods and functions?

Reading Time: 3 minutes 🕑

Last updated: October 18, 2021.

Don’t let the terminology fool you: a method and a function are practically the same thing!

A method is just a function stored in an JavaScript object.

In JavaScript objects, we can store data in key-value pairs (i.e. properties):

const user = {
	id: 237610,
	username: "james",
	premiumMember: true,
}

We can use dot notation to access the value of a property by entering its key:

console.log(user.id) // 237610
console.log(user.username) // james
console.log(user.premiumMember) // true

The value can be a string, number or boolean value. It can also be a function.

To store a function inside this object, we define it as the value of a property.

const user = {
	id: 237610,
	username: "james",
	premiumMember: true,
	newMethod: function() {
		alert("This method fires this alert")
		}
}

And access it with its key:

user.newMethod() // "This method fires this alert"

Why would we want to store a function in an object?

An important reason is we can apply the function (stored as a method) to the object to which is belongs.

For example, for string data we have available to us the toUpperCase() method. This function can be applied to the string data on which it is called:

let originalText = "some text"
let convertedText = originalText.toUpperCase() // method is applied to originalText
console.log(covertedText)

For this reason, you can think of a method as a function that is able to act on an object without have to pass it in as a parameter. We don’t have to do this because it is already associated and stored on the object we wish to apply it to.

For an object (i.e. an array, a JavaScript object), the automatically accessible methods are stored in its ‘prototype’, which we can see by calling console.log() on that object.

Arrays are particularly method-rich type of object. Let’s create a new array so we can access its methods:

const cars = ["Volvo", "BMW", "Ford"];
console.log(cars)

Open your browser console log, expand the array prototype and you should see something like below.

You may already recognise some of these popular methods from usage. For example, push adds an element to the end of an array and unshift one to the beginning.

And this is what these are: functions stored as methods within a ‘prototype’ object.

We can access any method available on the ‘prototype’ object with single dot notation. For example:

cars.push() // ['Volvo', 'BMW', 'Ford', 'Fiat']
cars.sort() // ['BMW', 'Fiat', 'Ford', 'Volvo']
cars.pop() // ['BMW', 'Fiat', 'Ford']
Console log screenshot

Note that not all of the items listed above are methods. Specifically, length is a property that stores a value representing the length of the prototype array object. Since we did not create any object in the prototype, this is listed as 0.

Viewing available methods for primitive data types

For primitive data types such as string or numeric, no prototype object exists. Thus, if we log a primitive data type to the console, we see no available methods. But we know that we can apply methods to these. For example, .toUpperCase on a string.

JavaScript makes this possible by wrapping primitive data types in an object wrapper at run time if needed. For example, if we call a method on a primitive type, JavaScript will wrap it in an object.

A trick to see available methods on primitive types is to try to access its prototype method using __proto__, which will trigger JavaScript to wrap the primitive type in an object wrapper:

const text = "Hello";
const number = 12345;
const boolean = true;

console.log(text.__proto__);
console.log(number.__proto__);
console.log(boolean.__proto__);

Summary

Methods are functions stored in objects. Usefully, these can act on the object on which they are called.

The available methods on an object vary depending upon its type. For JavaScript objects and arrays, we can see the methods available to us by logging them to the console and accessing their prototype. The available methods are listed there.

For primitive types, we have to add .__proto__ when logging to the console. This initiates the primitive data to be wrapped in an object wrapper, and as a result methods become available to us.