javascript에서 this란

Jungmin Lee·2021년 8월 30일
0

javascript

목록 보기
3/4

javascript에서 난해하고 헷갈리는 this에 대해 알아보자!

먼저 우리의 친절한 기본서인 mdn에서 this를 검색해보면

"this의 값은 함수를 호출하는 방법에 의해 결정된다"라는 문구를 볼 수 있다.

여기서 핵심은 호출하는 방법이다. '누가 선언했냐'가 아니라 '누가 호출했냐'이다.

자바스크립트에서는 선언 했을 때 or 호출 했을 때 정해지는 녀석들이 있는데 this는 호출했을 때 정해지는 녀석이다.

그럼 this에 대해 크게 4가지로 나뉠 수 있는데 하나씩 살펴보자.

this를 실행하는 4가지 방법

1.Function 호출

일반 함수를 실행 시켰을 때 this값이 어떻게 되는지 살펴보자.
여기서 this는 global object(브라우저상에선 window 객체)이다.
but, 엄격모드(strict mode)일땐 undefined가 나타난다.

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

여기서 foo함수를 호출할 때 위치는 글로벌 스코프이기에 this는 window가 된다.

2.Method 호출

this함수를 호출할때 함수 '.'(dot notation)을 사용하여 메소드를 실행 시키면 this는 .(dot notation) 앞의 객체가 this의 값이 된다.
밑에 예시를 한번 살펴보자

let name = 'tiger';
let animal = {
  name: 'monkey',
  foo: function foo() {
    console.log(this.name)
  }
};
animal.foo();

여기서 animal 객체 안 foo함수를 보자
여기서 this는 어디냐고 물어보면 아직 모른다
왜냐면 아직 선언이 되지 않았기 때문에...
하지만 그 밑에 animal.foo()라고 호출을 함으로써 foo 함수 안에 있는 this는 animal이 된다.
이역시 누가 호출하냐라는 개념만 이해하면 쉽게 알 수 있는 부분이다.

3.new 키워드를 이용한 생성자 호출

new키워드는 class를 만들고 새로운 인스턴스(객체)를 생성 할때 사용한다.

class Counter {
  constructor() {
    this.value = 0; 
    // 생성자 호출을 할 경우, this는 new 키워드로 생성한 Counter의 인스턴스이다
  }
  increase() {
    this.value++
  }
  decrease() {
    this.value--
  }
  getValue() {
    return this.value
  }
}
let counter1 = new Counter() // 생성자 호출
counter1.increase()
counter1.getValue() // 1

위의 예제에서 class는 Couter이고 인스턴스(객체)는 couter1 이다.
인스턴스(객체)에서 counter1.increase()를 실행하면 increase메소드 안에 있는 { this.value++ }가 실행되는데 여기서 this는 couter1를 의미한다.
즉, couter1.value++을 실행하기 때문에 couter1.getValue()를 실행 했을 시 couter1의 value값은 1이 출력된다.

4.call,apply,bind

.call, .apply 호출은 명시적으로 this를 지정하고 싶을 때 사용한다.
첫번째 인자가 항상 this값이 됩니다.
예시를 보자.

let age = 50;
function foo() {
  console.log(this.age);
}
let A = { 
  age: 20
};
let B = {
  age: 25
};
foo(); // 글로벌 스코프이기에 50이 나온다.
// 선언은 글로벌이지만 call과 apply를 사용해서 this값을 변경해주었다.
foo.call(A); // 20
foo.apply(B); // 25

call과 apply의 차이를 알기위해 위와 비슷한 다른 예시를 보자.

let age = 50;
function foo(1,2,3,4,5) {
  console.log(this.age);
}
let A = { 
  age: 20
};
let B = {
  age: 25
};
foo(); // 글로벌 스코프이기에 50이 나온다.
// 선언은 글로벌이지만 call과 apply를 사용해서 this값을 변경해주었다.
foo.call(A, 1, 2, 3, 4, 5); // 20
foo.apply(B, [1,2,3,4,5]); // 25

코드를 보면 알겠지만 call과 apply의 첫번째 인자는 this값이고 그 이후 값은 parameter이다.
하지만 call은 2번째부터 쭈~욱이고, apply이는 인자가 2개만 들어가고 2번째 인자에는 배열이 들어간다.
즉, 배열이 있고 없고 차이이다.
굳이 암기를 하지 않아도 되지만 약간의 암기 팁을 주자면 call은 apply에 비해 상대적으로 길이가 짧으니깐
배열이 '없다' 이고 apply는 call보다 상대적으로 기니깐 배열이 '있다'로 기억하면 헷갈리지 않을 것 같다.

마지막으로 bind에 대해 알아보자
apply,call과 비교하기 위해 위에와 비슷한 코드를 수정해보겠다.

let age = 50;
function foo(1,2,3,4,5) {
  console.log(this.age);
}
let A = { 
  age: 20
};
let B = {
  age: 25
};
foo(); // 글로벌 스코프이기에 50이 나온다.
// 선언은 글로벌이지만 call과 apply를 사용해서 this값을 변경해주었다.
foo.call(A, 1, 2, 3, 4, 5); // 20
foo.apply(B, [1,2,3,4,5]); // 25
// bind 사용법
let bar = foo.bind(A);
// parameter는 일반 함수 호출과 똑같다.
bar(1,2,3,4,5);

bind는 apply,call이랑은 다르게 호출할때 사용할 수 없다.
그래서 이렇게 새로운 변수를 선언하고 거기서 bind함수로 this값을 설정한다.
그리고 그 변수(bar)를 호출하면 this는 bind를 한 A가 된다.


이렇게 javascript의 this에 대해 정리해보았다.
완벽하진 않지만 그래도 기본 개념 이해하기에는 충분할거라 생각된다.
죰 더 공부가 필요하면 mdn에 검색해보면 많은 내용이 있으니 그걸 참고하면 좋을 것 같다.

profile
Front-end developer who never gives up.

0개의 댓글