Understanding This, Bind, Call and Apply in JavaScript
Many of you may have been asked about This keyword in an interview. It is a really important concept in JavaScript yet slightly confusing to new developers. Today let us disscuss this, apply, call and bind in JavaScript.
#
This in JavaScriptNot like other programming languages where this always refers to the current instance of the class, this in JavaScript depends on how a function is called. The usage of apply, call and bind methods can determine the value of this. Let's use an example to help us understand this.
var test = { func: function () { console.log(this.bar); }, prop: 1,};
var func = test.func;var prop = 2;
test.func(); // 1func(); // 2
In the example above, we can see that two ways of calling func() generated different results. The reason is that test.func() ran in the context of test where this refers, whereas the secoond func ran in the global context.
#
Call, Apply and BindWe use call(), apply() and bind() methods to set the this keyword independent of how the function is called. This is especially useful for the callbacks.
The call() and apply() methods set the this inside the function and immediately executes that function. The only difference between call() and apply() is that the apply() method accepts an array of arguments instead of comma separated values.
function.call(thisArg, arg1, agr2, ...)
function.apply(thisArg, [argumentsArr])
The code below will help us understand how call() and apply() work:
Function.prototype.call = (context, ...args) => { context = context === undefined || context === null ? window : Object(context); context.fn = this; const result = context.fn(...args); delete context.fn; return result;};
Function.prototype.apply = (context, args) => { context = context === undefined || context === null ? window : Object(context); context.fn = this; const result = args ? context.fn(...args) : context.fn(); delete context.fn; return result;};
Not like call() and apply(), the bind() creates a new function and sets the this keyword to the specified object.
function.bind(thisArg, optionalArguments)
Function.prototype.myBind = (context, ...args) => { if (typeof this !== "function") { throw new TypeError("error"); } context = context === undefined || context === null ? window : Object(context); self = this; return (...bindArgs) => { return self.apply(context, [...args, ...bindArgs)])};
#
Arrow FunctionsArrow functions do not have their own this binding. Instead, they go up to the next level of execution.
It can be useful to use the arrow function in cases where you really want this to refer to the outer context. For example, if you had an event listener inside of a class, you would probably want this to refer to some value in the class.
Reference: AWS S3 Doc, Medium(JavaScript Fundmentals)