자바스크립트의 this

2022. 8. 4. 21:00IT/Concept

반응형

 

자바스크립트에서 this의 쓰임새는 대표적인 객체지향 언어인 Java 등과 약간 다르다. 자바스크립트에서는 함수 호출 방식에 따라 this에 바인딩 되는 객체가 달라진다.


1. 자바스크립트 함수 호출 방식

자바스크립트에서 함수 호출 방식은 크게 다음 4가지가 있다.

  1. 일반적인 함수 호출
  2. 메소드 호출
  3. 생성자 함수 호출 (객체 생성 함수)
  4. apply/call/bind 호출

각각의 경우에 대한 this 바인딩을 알아보자.

이후 화살표 함수에서의 this 바인딩에 대해 알아보자.

 

2. 일반적인 함수 호출

this는 전역 객체를 가리킨다.

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

foo(); // window

 

3. 메소드 호출

this는 해당 메소드를 소유한 객체에 바인딩된다.

var person = {
  name: 'Lee',
  printName: function() {
    console.log(this.name);
  }
}

person.printName() // "Lee"

 

4. 생성자 함수 호출

객체를 생성하는 역할을 하는 생성자 함수를 호출할 경우, this는 새로 생성된 빈 객체에 바인딩된다.

함수의 인자로 전달받은 값을 객체의 속성에 할당하기 위해 this 키워드를 사용할 수 있다.

 

5. apply, call, bind 호출

apply, call, bind 메소드를 통해 this를 특정 객체에 명시적으로 바인딩 가능하다.

 

6. Arrow Function과 this

화살표 함수에는 this가 존재하지 않는다. 덕분에 화살표 함수의 this는 언제나 상위 스코프의 this를 가리킨다. 때문에 화살표 함수에서는 call, apply, bind 메소드를 사용해 this를 변경할 수 없다.

 

그리고 이것이 바로 화살표 함수를 주로 사용하게 되는 이유 중 하나다.

화살표 함수는 1.익명함수로만 사용가능하며, 2.생성자 함수로 사용할 수 없는 제약이 있다.

그럼에도 그 특유의 심플함과 this 바인딩 특성으로 인해 자주 사용한다.

 

예를 들어, 다음과 같은 상황을 살펴보자.

함수를 호출 시 그 함수 내부의 this는 지정되지 않기 때문에 전역 객체를 가리킨다.

이것이 일종의 JS 설계 오류라고 지적하는 사람들도 존재한다.

const person = {
  name: 'Mesotes',
  foo1: function() {
    const foo2 = function() {
      console.log(this.name);
    }
    foo2();
  }
};

person.foo1();	// undefined

이때 화살표 함수를 사용하면 상위 스코프의 this를 가리키기 때문에 이 문제는 해결된다.

const person = {
  name: 'Mesotes',
  foo1: function() {
    const foo2 = () => {
      console.log(this.name);
    }
    foo2();
  }
};

person.foo1();	// Mesotes

 

한편, 이러한 특성으로 인해 화살표 함수를 메소드로 사용 시 주의해야한다.

여기서 this는 상위 스코프인 전역 객체를 가리키기 때문에 undefined를 출력하게 된다.

const person = {
  name: 'Mesotes';
  callName: () => console.log(this.name);
}

person.callName();	// undefined

더 자세히 알아보기

관련서적: 모던 자바스크립트 Deep Dive

 

 

 

 

-학습을 진행하며 남기는 지식 포스팅-

 

-부족한 설명이 있다면 부디 조언 부탁드립니다-

 

 

 

 

이 포스팅은 쿠팡 파트너스 활동의 일환으로,

이에 따른 일정액의 수수료를 제공받습니다

반응형

'IT > Concept' 카테고리의 다른 글

Javascript의 클로저란?  (0) 2022.08.11
Javascript의 프로토타입이란?  (0) 2022.08.08
var, let, const, 그리고 Hoisting  (0) 2022.08.01
웹의 역사, 그리고 프론트엔드  (0) 2022.07.28
Computing Systems, 그리고 추상화  (0) 2022.06.14