‘this’ in Javascript

Scope vs Context

What is Scope?

function foo() {
const bar = true;
return bar;
};
console.log(foo()); // true
console.log(bar); // ReferenceError: bar is not defined

What is Context?

function foo() {
this.bar = true;
return bar;
};
console.log(foo()); // true
console.log(bar); // true

`this` refresher

"use strict";
var x = this; # [object Window]
var person1 = {
fullName: function() {
return this.firstName + " " + this.lastName;
}
}
var person2 = {
firstName:"John",
lastName: "Doe",
}
person1.fullName.call(person2); // Will return "John Doe"

[1].Context — globally and inside a function.

[2].Context — under 2nd level function.

[3]. Context — when the function is defined globally and used under an object (Implicit Binding).

Global Context

var myFunction = function(){
console.log(this);
console.log(this=== window);
}

myFunction();
// Output: Window object. In strict mode value will be undefined

As an object method

var val = 37;
var myObj = {
val : 10,
someFunction : function(){
console.log(this.val);
//Output: 10 since the value of this is equal to myObj
console.log(window.val); //Output: 37
console.log(this === myObj) // true
console.log(this)//Output: myObj object
}
}

myObj.someFunction();
//Variable defined in global scope
var val = 37;

var myObj = {
val : 10
}

var someFunction = function(){
console.log(this.val);
console.log(window.val);
console.log(this === myObj);
console.log(this);
console.log(this === window)
}

myObj.objectFunc = someFunction;
myObj.objectFunc();

/*
Output:
1. 10
2. 37
3. true
4. myObj
5. false
*/

someFunction();
/*
Output:
1. 37
2. 37
3. false
4. window
5. true
*/

As a constructor

function ConstructorFunc(value){
this.someValue = value;
}

var obj1 = new ConstructorFunction(20);
console.log(obj1.someValue)//Output: 20

‘this’ inside an IIFE

// IIFE outside any function 
(function() {
console.log(this); // Output: Window object
})()


// IIFE inside an object function
var obj = {};

var someFunc = function() {
console.log("Functions this");
console.log(this === obj); // true
console.log('++++++++++++++++++++++++++');

// IIFE
(function() {
console.log("IIFE this");
console.log(this); // Output: Window object
console.log("IIFE");
})()
};

obj.func = someFunc;

obj.func();

Event handler in JavaScript

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div id="divId">Hello</div>
<script type="text/javascript">
var id = document.getElementById('divId').addEventListener('click', clickMe, false);

function clickMe(event) {
console.log(event.currentTarget);
console.log("CLick Me");
console.log(this);
}
</script>
</body>
</html>

“this” inside arrow functions

this.robot = "global";
const thisRobots = {
robot: "local_1",
anotherRobotName: function (robot = "new_local") {
return this.robot;
},
details: {
robot: "local_2",
robotName: function () {
return this.robot;
},
arrowrobotName: () => this.robot
}
};
console.log(thisRobots.details.robotName());
console.log(thisRobots.details.arrowrobotName());
console.log(thisRobots.anotherRobotName());
# local_2
# global
# local_1
const func = () => { return this };
let obj = {func, a: 10}
obj.func(); # window
const a = () => {
return this;
}
a() === window;
# true

◉ “this” in global scope

this.name = "RSSB";
console.log(window.name); # anil
// this is a public property of window means accessible from outsidethis.name = {
firstname: "anil"
}
this.name.firstname; # anil
OR
window.name.firstname; # anil

◉ “this” inside node.js

console.log(this);    // {}
this.foo = 'bar' ;
console.log(this); // { foo: 'bar' }

◉ `this` inside an object

let name = {
firstname: "anil"
}
name.firstname; # anil
this.name.firstname; # TypeError: cannot read property of undefined

◉ `this` inside a method

let name = {
firstname: "anil",
getFullName: function(){
return this.firstname;
}
};
console.log(name.getFullName()); # anil

◉ `this` inside a function (outside of an object):

this.name = "RSSB";
const getFullName= function(){
return this.firstname;
}
getFullName();
# RSSB
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
"use strict"
this.name = "RSSB";
const getFullName= function(){
return this.firstname;
}
getFullName();
# undefined
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

"call" to the rescue for above
"use strict";
this.name = "RSSB";
const getFullName= function(arg){
return this.firstname + arg;
}
getFullName.call(this, "to all"); # RSSB to all

◉ `this` inside a nested function

◉ `this` inside classes

Using Bind in Class Methods

import React from 'react';  class Counter extends React.Component { 
constructor(props) {
super(props);
this.state = { count: 0 };
this.addOne = this.addOne.bind(this);
};
addOne(event){
this.setState({ count: this.state.count + 1 });
};

render(){
return (
<button type="button" onClick={this.addOne}>
Click Me
</button>
);
};
};

Implicit Binding with Arrow Functions

import React from 'react';class Counter extends React.Component { 
state = { count: 0 };
addOne = (event) => {
this.setState({ count: this.state.count + 1 });
};

render(){
return (
<button type="button" onClick={this.addOne}>
Click Me
</button>
);
};
};

JavaScript ‘this’ in Regular, Arrow functions and Methods — a Short Circuit Example

this.robot = "Hal 9000";
function robotName(){
console.log(this.robot)
}
function robotName() {  
this.robot = "Astro Boy";
console.log(this.robot)
}
// => Astro Boy
thisRobots.details.robotName(); 
# Astro Boy
thisRobots.details.arrowrobotName();
# Hall 9000
thisRobots.anotherRobotName();  # calling without arguments
# Johnny 5
!

◉ `this` exercises

function func() {
return this;
};
func(); # global window object
# But there are three methods we can use to change the meaning of this when we call it: call , apply and bind .# Say we wanted this to represent the string 'Hello World!' , we can do that in a number of ways:func.call('Hello World');
func.apply('Hello World');
func.bind('Hello World')();
# Each line of the code above would return the string 'Hello World!'const a = 1;
const obj = { a: 2 };
function whatIsA() { return this.a };
whatIsA();            // 1
whatIsA(obj); // 1
whatIsA.call(obj); // 2
whatIsA.apply(obj); // 2
whatIsA.bind(obj)(); // 2
var x = "global";
const foo= {
x: 10,
getX: function () {
return this.x;
}
};
let y = foo.getX;
console.log(y()); # global
const foo = {
x: 10,
getX: function () {
return this.x;
}
};
let y = foo.getX;
y = y.bind(foo); or y.bind(foo)();

References:

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.

Get the Medium app