본문 바로가기

JAVA SCRIPT

[JAVA SCRIPT] this

자바 스크립트에서의 this는

 

누가 호출했는지(호출한 문맥)에 따라서 동적으로 변경된다.

 

먼저 그냥 this를 콘솔로 출력해보면

 

 

브라우저 환경에서의 글로벌 객체인 Window가 나온다.

 

this를 콘솔로 출력하는 간단한 함수를 만들어서 다시 출력해 보자.

 

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

 

 

this를 콘솔로 출력하는 이 함수도 Window를 가르키고 있다.

 

글로벌 환경에서 simpleFunc() 함수를 호출하는것은

 

 

window에서 호출하는것과 동일하기 때문이다.

 

이번엔 Counter 클래스를 만들고 멤버 변수에 increase() 함수를 만들어 this를 콘솔로 출력해 보자.

 

class Counter {
  count = 0;
  increase = function () {
    console.log(this);
  };
}

const counter = new Counter();
counter.increase();

 

이번엔 this가 Counter를 가르키고 있다.

 

counter에서 increase() 함수를 호출했기 때문이다.

 

counter.increase();

 

또 이번엔 func 변수에 counter의 increase 함수를 할당해 보자.

 

class Counter {
  count = 0;
  increase = function () {
    console.log(this);
  };
}

const counter = new Counter();
counter.increase();
const func = counter.increase;
func();

 

window가 나올려나? 싶었지만 이번엔 undefined가 나온다.

 

this는 원래 Counter 클래스를 가르키고 있었으나

 

increase() 함수의 포인터를 func 변수에 할당했기 때문에 this의 정보를 잃어버리게 되었다.

 

let 과 const 로 선언된 변수는 window에 등록되어 있지 않기때문에

 

func 변수를 호출하는것은 window가 아닌 아무것도 아닌것이(?) 호출하는 것이다. 여기서 살짝 어렵다..😐

 

 

 

 

다시 처음으로 돌아가서

 

function helloWorld() {
  console.log("Hello World!");
}
window.helloWorld(); // Hello World

 

함수를 선언하면 window(글로벌 객체)에 등록되서 사용할 수 있다.

 

하지만 let, const로 변수를 선언하면 window에 등록되지 않아 사용할 수 없다.

 

const hello = 'hello';
let world = 'world';

window.hello; // ❌❌❌
window.world; // ❌❌❌

 

번외로 var로 변수를 선언하면 window에 등록이 된다.

 

 

다시 이번엔 빈 클래스를 만들고 인스턴스에 counter의 increase 함수를 할당해보자.

 

class Person {}
const person = new Person();
person.run = counter.increase;
person.run();

 

this가 Person 클래스를 가르키고 있다.

 

person.run();

 

이렇게 종잡을 수 없는 자바 스크립트의 this는 bind를 통해서 제어할 수 있다. (사전적 의미 : 묶다.)

 

const func = counter.increase; // undefined
const func = counter.increase.bind(counter);
func();

 

this의 정보를 잃어버리지 않기 위해서 counter 객체와 묶은 상태에서 변수에 할당해 주면

 

 

이제는 undefined가 아닌 Counter 객체를 가르키게 된다.

 

 

 

자바 스크립트에서의 this는 호출하는 문맥에 따라서 동적으로 변하기 때문에
한 객체에 지정하고 싶을땐 bind 함수를 이용해서 묶어줘야 한다.

 

 

 

그런데 bind 함수를 이용하는것 말고 또 다른 방법이 있다.

 

바로 클래스에서 함수를 정의할 때 화살표 함수(Arrow function)를 이용하면 bind 함수로 묶지 않아도

 

선언될때의 상위 스코프를 가르키도록 정적으로 결정된다.

 

class Counter {
  count = 0;
  increase = () => {
    console.log(this);
  };
}

const counter = new Counter();
const func = counter.increase;
func();

 

이제 this에 대해서 어느정도 감이 잡힌것 같다! 상황에 따라서 화살표 함수나 bind 함수를 잘 이용하자.

'JAVA SCRIPT' 카테고리의 다른 글

[JAVA SCRIPT] Intl API  (0) 2022.11.23
[JAVA SCRIPT] DOM 간단 정리  (0) 2022.06.30