[JS] 자바스크립트에서의 this
포스트
취소

[JS] 자바스크립트에서의 this

자바스크립트에서의 this는 어떻게 호출되었는지, 호출 패턴에 따라 값이 결정된다.
다른 언어와는 개념이 다르며, 선언이 되어있는 곳이 아닌 호출에 따라 달라진다 !!

this가 호출되어있을 때, 어떻게 달라질까?

1. global에서 this 호출

global this

크롬 콘솔 창에 this를 입력하면 window라고 나온다. 기본적으로 this는 window인 것을 알 수 이있다.

그럼 일반 함수에서의 호출은 어떨까?


2. 일반 함수에서의 호출

1
2
3
4
5
function exFunction() {
  console.log(this);
}

exFunction(); // window
1
2
3
4
5
6
7
'use strict';

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

exFunction(); // undefined

기본 함수에서 작성한 것과 use strict 모드에서는 값이 다르게 나온다.

❓ strict 모드는 undefiend 일까?

use strict 는 ES5에서 도입된 것으로 예측하지 못하는 오류를 좀 더 쉽게 해결할 수 있게 해준다.

그래서 전역 객체를 실수로 변경할 경우 방지해주고, this를 항상 참조하는 것이 아닌 undefined 로 설정하여 함수가 기대하지 않은 컨텍스트에서 실행되는 것을 방지해준다.


3. 메서드에서의 호출

1
2
3
4
5
6
7
let obj = {
  a: function () {
    console.log(this);
  },
};

obj.a(); // obj

객체의 메서드를 호출할 때 this를 해당 객체에 바인딩해준다.

❓ 메서드 안에 함수를 호출하면?

1
2
3
4
5
6
7
8
9
10
11
12
let obj = {
  a: function () {
    console.log(this); // obj

    function aInnerB() {
      console.log('aInnerB 호출 this >> ', this); // window
    }
    aInnerB();
  },
};

obj.a();

this는 기본적으로 전역 객체에 바인딩이 되기 때문에, 메서드 내의 내부함수일 경우에도 window에 바인딩된다.


4. 생성자 함수로서의 호출

1
2
3
4
5
6
7
8
9
10
function Person(name, age) {
  this.name = name;
  this.age = age;
}

let sine = new Person('sieun', 24);
console.log(sine); // Person { name: 'sieun', age: 24 }

let sine2 = Person('sieun', 24);
console.log(sine2); // undefined

new 키워드를 사용해서 객체를 생성해야만 생성자 함수이고, 키워드를 붙이지 않으면 일반 함수다. sine2에서 undefined가 나온 이유는 현재 함수의 리턴 값이 없기 때문!

또한 많은 사람들이 new 키워드를 사용하지 않아 ES6부터가 class가 도입되었다.

❓ 그럼 위에 생성자 함수 로직은 어떨까?

1
2
3
4
5
6
7
8
9
function Person(name, age) {
  // 생성자 함수 코드 실행 전 ①
  this.name = name;  // ②
  this.age = age;    // ②
  // 생성된 함수 반환       ③
}

let sine = new Person('sieun', 24);
console.log(sine.name); // sieun


5. call/apply/bind 호출

call, apply, bind는 자바스크립트 내장 객체다. 얘네를 사용하면 명시적으로 this를 바꾸게하고, 객체를 가리키게 한다.

[메서드 호출할 때 공통으로 사용할 함수]

1
2
3
function sineDesc(name, year) {
  console.log(`My name is ${name}, and ${year} year ${this.gender}`); 
}

call

1
2
let sine = { gender: 'woman' };
sineDesc.call(sine, 'Sieun', 24); // My name is Sieun, and 24 year woman

call 사용할 때는 맨 처음에 this로 설정할 값을 넣어주고 그 뒤에 함수에게 전달해줄 인자들을 적어야 한다.

apply

1
2
let sine = { gender: 'woman' };
sineDesc.apply(sine, ['Sieun', 24]); // My name is Sieun, and 24 year woman

apply는 call과 비슷하게 사용되지만, 함수에게 전달해줄 인자들을 배열[]로 감싸서 넘겨줘야 한다.

bind

1
2
3
4
let sine = { gender: 'woman' };
let bindSineDesc = sineDesc.bind(sine);

bindSineDesc('Sieun', 24); // My name is Sieun, and 24 year woman

bind는 함수의 this 값을 특정 값으로 새로운 함수를 반환해준다. 이렇게 생성된 함수는 원할 때마다 사용이 가능하다.


🔖 결론

  • 기본 함수에서 this를 호출하면 window, strict 모드에서 this를 호출하면 undefined !!
  • 내장 함수는 선언이 되어있는 곳 상관없이 언제든 this를 전역 객체에 바인딩한다.
  • call, apply, bind를 사용하여 this를 특정 객체에 명시적으로 바인딩할 수 있다.



Reference

자바스크립트의 this는 무엇인가?

함수 호출 방식에 의해 결정되는 this

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

[JS] 자바스크립트는 싱글스레드인데 어떻게 멀티스레드처럼 동작할 수 있을까?

[Error] ReactNative styled-components theme 타입 인식 못하는 에러