[JavaScript] this keyword cleanup


Writing time : 2021-07-18 01:01:58

Introduction

In java script, this is the object referenced at the time the function is called.
When this is declared, the object referred to by this may be different depending on the scope in which the code is called.
Let's find out which object this refers to in various cases

global context

Called this in the global execution context refers to the global object.
The global object is the window object in the browser and the Global object in Node.js.
In the code below, this refers to the global object.

var count = 10  
  
// 10  
console.log(this.count)  
  
// equal  
if(this == window){  
    console.log("equal")  
}  


function context

General function (if not in strict mode)

The this of a general function called from the global object refers to the global object.

var count = 10  
  
function foo(){  
   "use strict";  
  
  // 10  
  console.log(this.count)  
  
  // equal  
  if(this == window){  
      console.log("equal")  
  }  
}  
  
foo()  


Regular function strict mode

If the general function called from the global object is in strict mode, this is assigned undefined.
The reason undefined is assigned to a function that is called globally is because this is used to check the object that refers to itself in a method or constructor function, and it is not necessary to use it in a general function.

var count = 10  
  
function foo(){  
   "use strict";  
  
  // undefined  
  if(this == undefined){  
      console.log("undefined")  
  }  
}  
  
foo()  


constructor function

This used in the constructor function refers to the instance to be created.
In the code below, this used in the getCount method refers to the Foo object created by the Foo constructor function.

function Foo(){  
  this.count = 10  
  this.getCount = function(){  
    return this.count  
  }  
}  
  
const foo = new Foo()  
console.log(foo.getCount())  


method

This used in the method is bound to the object that called the method.
In the code below, the value of the count property declared in the foo object is output because getCount is called by the foo object.

const foo = {  
    count: 10,  
    getCount : function() {  
        return this.count  
    }  
}  
  
// 10  
console.log(foo.getCount())  


Let's check the case where a method declared in an object literal is called in another object literal.
In the code below, the getCount function bound to the property of the foo object literal is bound to the bar object literal.
getCount is declared in the foo property, but the object that called the function is a bar object literal, so the count variable declared in the bar object literal is output.

const foo = {  
    count: 10,  
    getCount : function() {  
        return this.count  
    }  
}  
  
const bar = {  
    count: 20  
}  
  
// bind getCount function to the bar object  
bar.getCount = foo.getCount  
  
// 20  
console.log(bar.getCount())  


callback function

The callback function is treated the same as the global function.
In the code below, the this of the callback function passed to setTimerout refers to the global object window, so the value 20 stored in the global object's count property is output.

window.count = 20  
  
const foo = {  
  count: 10,  
  printCount : function(){  
    setTimeout(function(){  
      // 20  
      console.log(this.count)  
    },0)  
  }  
}  
foo.printCount()  


In a general function used as a callback function, this variable is additionally declared and used as follows as a way to match this with the method's this.
However, it is recommended to use the arrow function, which will be described next, rather than the method below.

window.count = 20  
  
const foo = {  
  count: 10,  
  printCount : function(){  
    const that = this      
    setTimeout(function(){  
      // 10  
      console.log(that.count)  
    },0)  
  }  
}  
foo.printCount()  


arrow function

Arrow functions refer to this of the parent scope.
In the code below, an arrow function is used for setTimer, and the parent scope of the arrow function is a foo object, so the value 10 stored in the count property of the foo object is output.

window.count = 20  
  
const foo = {  
count: 10,  
printCount: function () {  
  setTimeout(  
    () => {  
      // 10  
      console.log(this.count)  
    }, 0)  
}  
}  
  
foo.printCount()  


If the arrow function is set as a method of the foo object instead of being passed as a callback to setTimer, it refers to the window object, which is the upper scope of the foo object.

window.count = 20  
  
const foo = {  
  count: 10,  
  printCount: () => {  
    // 20  
    console.log(this.count)  
  }  
}  
  
foo.printCount()  


Arrow functions are mainly used as callback functions, and it is recommended to use general functions instead of arrow functions in methods.

DOM inline event handler

This used in the inline function of a DOM element refers to an element in the DOM.
In the code below, this refers to the button element.

<!-- console 로그로 BUTTON 출력 -->  
<button onclick="console.log(this.tagName)">test</button>  


The this of a general function called in the inline function of the DOM element refers to the global object.

<button onclick="buttonClick(this)">test</button>  


<script>  
  function buttonClick(param){  
    // equal  
    if(this === window){  
      console.log('equal')  
    }  
  
    // BUTTON  
    console.log(param.tagName)  
  }  
</script>  


In the event function set with addEventListener, this refers to e.currentTarget.
In the code below, e.currentTarget is the button on which the click event occurred.

<body>  
  <button id="testButton">test</button>  
</body>  


<script>  
  function foo(e){  
    // equal  
    if(e.currentTarget === this){  
      console.log('equal')  
    }  
      
    // BUTTON  
    console.log(this.tagName)  
  }  
    
  const button = document.getElementById('testButton')  
  button.addEventListener('click', foo, false)  
</script>  


context

In the written article, the word context is used, such as global context and function context.
The word context is used because the criteria this binds to is based on the context, not the code written.


For example, this used in the code below refers to the window object because it is a function declared globally.

window.count = 10  
function printCount() {  
  // 10  
  console.log(count)  
}  
  
printCount()  


However, if a general function is also used as a method, this refers to the object that called the method.

window.count = 10  
  
function printCount() {  
  return this.count++  
}  
  
const myObject = {  
    count: 20,  
    foo: printCount      
}  
  
// 20  
myObject.foo()  
Previous post

Next post