A Function Or a Method?

Open the project folder

In our starter files, open the index.html page from this lessons folder:

03.Functions > 05.A-function-or-a-method

Example

JavaScript has lots of terminology which can take a while to get used to. Such as expressions and declarations which we just looked at. Something else we have used a lot is the words function and method. They can appear to be the same, and they pretty much are, but there is a key difference.

In the starter, we have a function which we have used earlier:

let bread = ['flour', 'yeast', 'salt', 'water'];
let brownies = ['butter', 'chocolate', 'flour', 'eggs', 'sugar'];

function checkAllergies(recipe, ingredient) {
  const hasIngredient = recipe.includes(ingredient);
  return hasIngredient;
}

Let’s also create another function and you will see why in a moment. This is going to check how many ingredients a recipe has and we can add this below other function:

function numberOfIngredients(recipe) {
  return recipe.length;
}
console.log(numberOfIngredients(bread)); // will log the number of items in the bread array (4)

This leaves us with 2 functions which are related to our ingredients and recipes. Let’s say we were creating more functions, more ways to check the recipe, it would be good to group all these functions together.

Grouping functions

And how do we group together lots of related values? We can use an object for this. We have looked at objects so far like this:

let user = {
  name: 'chris',
  occupation: 'developer'
}

Objects are not just used for storing primitive values like we have here (strings), is can also have object types such as other objects, arrays, and functions.

For this we can create an object for our functions at the bottom of our example:

let checkRecipes = {
  // first set up our property names:
  checkAllergies:
  numberOfIngredients:
}

Then the functions can be cut and pasted over:

let checkRecipes = {
  checkAllergies: function checkAllergies(recipe, ingredient) {
    const hasIngredient = recipe.includes(ingredient);
    return hasIngredient;
  },
  numberOfIngredients: function numberOfIngredients(recipe) {
    return recipe.length;
  },
};

Make sure to separate each property with a comma, and the console.log can be removed to avoid any errors. The function names can also be removed since we now have the property name to match:

let checkRecipes = {
  checkAllergies: function (recipe, ingredient) {
    const hasIngredient = recipe.includes(ingredient);
    return hasIngredient;
  },
  numberOfIngredients: function (recipe) {
    return recipe.length;
  },
};

Methods

Since our functions are now placed on an object, they are considered methods. And we call them on the object name, such as checkRecipes.numberOfIngredients(bread). This can be logged to the console:

let checkRecipes = {
  checkAllergies: function (recipe, ingredient) {
    const hasIngredient = recipe.includes(ingredient);
    return hasIngredient;
  },
  numberOfIngredients: function (recipe) {
    return recipe.length;
  },
};
console.log(checkRecipes.numberOfIngredients(bread));

And this is how the array methods work which we have looked at. Type the following into console:

brownies.

Brownies is an array, which remember is a special object type. And we should see all the methods and properties which are available on this object when using the . just after.

Just to recap, brownies is a type of object. And since properties like every() and filter() are part of this object, they too are methods.

Objects like checkRecipes can contain any data type, we can also mix in primitives:

let checkRecipes = {
  // maxRecipes contains a primitive number value:
  maxRecipes: 1000,
  checkAllergies: function (recipe, ingredient) {
    const hasIngredient = recipe.includes(ingredient);
    return hasIngredient;
  },
  numberOfIngredients: function (recipe) {
    return recipe.length;
  },
};
console.log(checkRecipes.maxRecipes);

We now know a function placed as a property on an object is considered a method in JavaScript.

Accessing properties on the same object

Sometimes, these methods may also need to refer to other properties on the same object. If we wanted to check we had not reached this maximum number of recipes, we could do it like this:

let checkRecipes = {
  // 1. add current recipes total:
  currentRecipes: 137,
  maxRecipes: 1000,
  checkAllergies: function (recipe, ingredient) {
    const hasIngredient = recipe.includes(ingredient);
    return hasIngredient;
  },
  numberOfIngredients: function (recipe) {
    return recipe.length;
  },
  // 2. then a method to calculate the number of recipes left:
  recipesLeft: function () {
    return maxRecipes - currentRecipes;
  },
};

Change the console log to run this new method:

console.log(checkRecipes.recipesLeft());

You will see an error in the console:

Uncaught ReferenceError: maxRecipes is not defined

This is because to access other properties on the same object, we need to use the this keyword:

recipesLeft: function () {
  return this.maxRecipes - this.currentRecipes;
},

The console should now show the result. Let’s see the result if we log this inside our method:

recipesLeft: function () {
  console.log(this);
  return this.maxRecipes - this.currentRecipes;
},

This will log all our checkRecipes object:

{currentRecipes: 137, maxRecipes: 1000, checkAllergies: ƒ, numberOfIngredients: ƒ, recipesLeft: ƒ}

There is an upcoming section dedicated to things like scope and what the this keyword is in more detail. And an arrow function which we briefly covered earlier acts differently to this, and we will cover this in the next lesson.