Skip to content

Using this and arguments

This and Arguments in JS

Apart from parameters being explicitly defined inside the function definition, there are two additional silent parameters getting passed down to the function itself. These silent parameters are called implicit parameters: this and arguments. They are not listed in the signature of any function but can be accessible within the function itself. The this parameter (also called functional context), represents the object on which the function is invoked, while the arguments parameter is an iterable representation of all the arguments passed into the function call.

Arguments parameter

Arguments parameter refers to the collection of all arguments passed to a function. Regardless of the definition of the function, we can use the arguments parameter to access all function arguments. We don’t use the arguments parameter as widely in the new versions of the JS language. The new rest parameter handles the total collection of arguments. But it is still nice to know something about it.

The arguments parameter has a property named length that indicates exactly how many arguments there are in the definition of the function. We can obtain individual argument values by using array indexing notation, for example, arguments[0] to retrieve the first parameter in the list.

function testingArguments(a, b, c) {
  console.log(arguments.length);
  console.log(arguments[0]);
  console.log(a == arguments[0]);
  console.log(arguments[4]);
}

testingArguments(10, 'foo', true, 'fourth', 5);

We declared a function that takes three parameters, a, b and c. But we invoked the same function with five arguments. Inside the function, we play around with the arguments param, getting the length of the whole parameter (which would display 5), and getting individual elements through array notation. We even compared the variable a to the zeroeth argument, to make sure they are the same.

Keep in mind that the arguments parameter is not an array. Yeah, we access the element through array notation and it might have the length property. But it is not, and most other array methods will not work on the arguments object. The arguments parameter can access all arguments passed to the functions regardless of the declaration.

This parameter

Another implicit parameter passed to the function is the this parameter, also known as the function context. The value of the this parameter can be influenced by many different factors, but it most commonly points to the object that invoked the function. Knowing this is really important for JavaScript developers, and knowing how to determine where this comes from can help with debugging.

There are four ways we can invoke functions in JavaScript:

  • Regular function – function()
  • Object method – object.function()
  • Constructor – new Car()
  • Apply or call methods – function.call(object) or function.apply(object)
function regularFunction() {}

function ConstructorFunction() {}

let object = {
  objectFunction: function() {}
}

regularFunction();
let constructorObject = new ConstructorFunction();
object.objectFunction();
regularFunction.call(object);
regularFunction.apply(object)

Let’s mention them one by one!

Function Invocation

This is the default way of invoking functions. We use the () operator and we either reference the function by a variable or call it on its own.

// 'use strict'; uncomment for this to be undefined

function howMany() {
  console.log(this);
}

howMany();

When invoked in this manner the value of this will depend on whether the script has the strict directive. If we omitted the ‘use strict’ command, the this object would refer to the whole window object, otherwise, it would just be – undefined.

Object method invocation

When invoking a function that is a property of an object then the function context is the object itself. Which means that this becomes the object itself. We can simply test this by returning “this” instead of 5 in the body of the getSpeed() method below.

let car = {
  getSpeed: function() {
    // return this;
    return "5";
  }
}

car.getSpeed();

Constructor invocation

Constructor functions behave like any other function declaration/expression, the only difference being the syntax of invocation.

function PleaseCallMe() {
	return this;
}

new PleaseCallMe();

When we invoke a new constructor function, we go through a couple of special steps, including creating a new empty object, then passing that object to the constructor as this parameter and giving the object the function context, and in the end, the object is returned as the new value.

The real strength of the constructor function lies right there – in the ability to create a new object and to return it as a constructor value.

function PleaseCallMe() {
  this.pleaseCallMeMethod = function() {
    return this;
  }
}

let object1 = new PleaseCallMe();
let object2 = new PleaseCallMe();

console.log(object1.pleaseCallMeMethod() == object1);
console.log(object2.pleaseCallMeMethod() == object2);

Using a constructor we made sure that each invocation of the method will operate on the expected object.

Invoking with apply and call methods

We notice a common trope between the types of function invocations mentioned above. We (almost) always know what is the reference to this. For methods we know that is the object that the method belongs to. For top-level functions, it’s either the window object or undefined, and for constructors it is the new object instance.

We could also explicitly give the function context to any object we want! We do this through the use of apply and call methods.

function sumTwoNumbers() {
  let sumOfNumbers = this.number1 + this.number2;
  return sumOfNumbers;
}

let objectToSum1 = {
  number1: 5,
  number2: 5
}

let objectToSum2 = {
  number1: 2,
  number2: 2
}

console.log(sumTwoNumbers.apply(objectToSum1));
console.log(sumTwoNumbers.apply(objectToSum2));

The apply and call methods are more or less similar, the only difference being the syntax. For the apply method, we pass two parameters – the object to use as the functional context and the array of values to be used as invocation arguments. The call method is similar, except that we pass the arguments directly.

function aboutMe(name, age) {
    console.log("My name is " + name + ", I am " + age +" years old. I live in " + this.city);
}

let personCity = {
	city: 'Melbourne'
};

aboutMe.apply(personCity, ["John", 55]);
aboutMe.call(personCity, "Jane", 21);

Look at this! Not only did we provide our arguments inside the array for the apply method, or together with other arguments for the call method, we also picked up the city from the function context (which is the personCity object). The only difference between call and apply is the way how the arguments were supplied. Both of them take the object to use as the functional context, and then they accept one argument for apply, or any number of arguments for call.

Final Words

Hope you had fun reading about this and argument implicit parameters in JavaScript.

For more articles please click below, or check the blog.