Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

Front-end Developer

자바스크립트의 this는 무엇일까? 본문

JavaScript

자바스크립트의 this는 무엇일까?

Brad Daeho Lee 2021. 6. 20. 19:18

 

 

Javascript this를 공부해야지 해야지 하다가 드디어 공부를 하고 이렇게 정리를 해봅니다. this는 어떤 함수나 객체를 가르키게 되는데 어디서 호출되냐에 따라서 가르키는 함수 또는 객체가 달라집니다. 총 크게 6가지 경우가 있는데 어떤 경우에서 어떻게 변하는지 정리해보겠습니다.

 

1. 전역에서 쓴 this

전역에서 this를 호출하면 this는 Window라는 전역 객체를 가리키게 됩니다. (Node.js에서는 Global)

Window(전역 객체)는  javascript의 모든 객체, 함수, 변수들을 포함하고 있습니다.

//1. 전역에서 호출
var x = this;
console.log(x); //Window

 

2. 일반 함수 안에서 쓴 this

일반 함수 안에서 this가 호출이 되면 this는 함수의 주인에게 바인딩이 됩니다. 그리고 함수의 주인은 Window입니다.

var num = 0;
function addNum() {
  //this는 Window를 가르킵니다.
  this.num = 100;
  num++;
  
  console.log(num); // 101
  console.log(window.num); // 101
  console.log(num === window.num); // true
}
 
addNum();

this.num의 this는 window를 가르킵니다. 그래서  num은 전역변수 num을 가르키게 됩니다.

 

 

하지만, 예외인 경우가 있습니다. "use strict" 모드에서는 함수 안에서 this가 주인에게 바인딩이 안되서 Window가 되는게 아니라 undefinded가 됩니다.

"use strict";
 
var num = 0;
function addNum() {
  this.num = 100; //ERROR! Cannot set property 'num' of undefined
  num++;
}
 
addNum();

 

3. Method 안에서 쓴 this

method 안에서 할당된 this는 method를 호출한 객체로 바인딩 합니다.

var num = 0;
 
function showNum() {
  console.log(this.num);
}
 
showNum(); //0
 
var obj = {
  num: 200,
  func: showNum,
};
 
obj.func(); //200

 

4. EventListener 안에서 쓴 this

EventListener안에서는 html 요소(태그, 클래스 또는 아이디)를 가리킨다.

var div = document.querySelector('#div')
div.addEventListener('click', function () {
  console.log(this); //#div
});

 

5. 생성자 안에서 쓴 this

생성자 함수가 생성하는 객체로 this가 바인딩 됩니다.

function Man () {
    this.name = 'John';
}

// 생성자로 객체 선언
var john = new Man();

// this가 Man 객체를 가리키고 있어 이름이 정상적으로 출력된다
john.name; // => 'John'

 

혹여나 객체를 생성할 때 생성자 함수 앞에 new를 붙이지 않는다면 this는 생성되는 객체에 바인딩되지 않는다.

function Man () {
    this.name = 'John';
}

var john = Man();

john.name; // => name이 undefinded여서 error가 난다.

 

6. Arrow 함수에서 쓴 this

일반 함수에서는 this는 Window (전역 객체)를 바인딩하기 때문에 상위 객체 또는 함수를 바인딩 하기위해서는 Arrow function을 사용하면 된다.

 

일반 함수를 사용했을 때

let person = {
    name: "Brad",
    getName: function () {
        console.log(this) // method에 this를 할당했기 때문에 person 객체에 바인딩된다.
        setTimeout(function () {
          console.log(this) // window 객체를 가리킨다
          console.log(this.name); // undefined window객체안에 name이 없음으로!
      }, 1000);
  }
}

person.getName();

 

Arrow 함수를 사용했을 때

let person = {
    name: "Brad",
    getName: function () {
        console.log(this) // person 객체를 가리킨다
        setTimeout(() => {
          console.log(this) // person객체를 가리킨다
          console.log(this.name); // Brad 을 출력한다.
      }, 1000);
  }
}

person.getName();

 

7. call, apply, bind 메서드 사용

call(), apply()

call 과 apply 메서드는 첫 번째 인자를 this로 만들어주는 역할을 합니다.

function HowisThis() {
  console.log(this);
}
 
HowisThis(); //window
 
var obj = {
  x: great,
};

HowisThis.call(obj); //{x:great} HowisThis.apply(obj)로 써도 똑같습니다.

call 메서드의 인자안에 있는 obj가 HowisThis 함수안에 할당된 this가 obj가 됩니다.

 

 

call과 apply는 거의 같은데 차이점은 call()은 인수 목록을 받고 apply()는 인수 배열을 받는다는 차이가 있다.

function add(c, d) {
  return this.a + this.b + c + d;
}

var o = {a: 3, b: 3};

// 첫 번째 인자는 'this'로 사용할 객체이고,
// 이어지는 인자들은 함수 호출에서 인수로 전달된다.
add.call(o, 6, 6); // 18

// 첫 번째 인자는 'this'로 사용할 객체이고,
// 두 번째 인자는 함수 호출에서 인수로 사용될 멤버들이 위치한 배열이다.
add.apply(o, [20, 10]); // 36

 

bind()

ES5에서 도입이 되었는데, bind() 메서드 안에 obj를 호출하면 this는 원본 함수를 가진 새로운 함수를 생성하고 bind는 한 번만 동작을 합니다.

function f() {
  return this.a;
}

var g = f.bind({a: 'Brad'});
console.log(g()); // Brad

var h = g.bind({a: 'Daeho'}); // bind는 한 번만 동작함!
console.log(h()); // Brad

var o = {a: 29, f: f, g: g, h: h};
console.log(o.a, o.f(), o.g(), o.h()); // 29, 29, Brad, Brad

 

참고자료

자바스크립트 MDN this - Mozilla
(JavaScript) 자바스크립트의 this는 무엇인가? -ZeroCho Blog
[JS] 자바스크립트에서의 this :: nana_log - 나나

 

Comments