면접준비(4-2) JS : 함수와 this에 대한 정리(feat. 화살표 함수)

Edwin·2023년 6월 1일
0

면접준비

목록 보기
6/6
post-thumbnail

프로그래밍 언에서의 this


"this"는 프로그래밍 언어에서 사용되는 키워드로, 객체 내에서 현재 실행 중인 메서드나 함수가 속한 객체 자체를 참조하는 데 사용됩니다. "this"를 사용하면 객체 내에서 정의된 변수, 함수, 메서드 등에 접근할 수 있습니다.


객체 지향 프로그래밍에서 객체는 속성과 동작을 가지는데, 이러한 속성과 동작에 대해서 멤버(Member)라는 용어가 사용된다.

객체의 속성

일반적으로 프로퍼티로 불리며, 객체의 상태를 나타난다.

객체의 동작

함수 또는 메서드로 표현된다. 멤버 함수는 객체가 수행하는 특정 작업을 정의하고 실행하는데 사용된다.

this는 객체의 속성과 동작을 나타내는 멤버들을 캡슐화하여 객체의 내부에 쉽게 접근하고 조작할 수 있도록 해주는 특별한 키워드이다.

JS에서 this

Javascript에서 this는 일반적으로 사용되는 다른 언어의 용례와 다르다. 자바스크립트에서 this는 현재 실행 중인 함수의 호출 컨텍스트에 따라 동적으로 결정되는 객체(를 가리키는 특별한 키워드)입니다.이를 동적바인딩이라고 부른다.

ES6의 화살표 함수(arrow function)는 this를 바인딩하지 않습니다. 대신에 화살표 함수는 선언된 시점의 렉시컬 스코프를 상속받아 정적으로 상위 스코프에 있는 this를 참조하고 이로 인해 화살표 함수 내에서 사용된 this는 일반 함수와는 다른게 동작한다..

일반 함수에서의 this는 함수를 어떻게 호출했느냐에 따라 동적으로 결정되지만, 화살표 함수에서의 this는 상위 스코프의 this를 그대로 상속받아 사용한다. 이를 통해 화살표 함수는 주로 상위 스코프의 this를 간편하게 참조한다.

this의 이러한 성격을 잘 알고 사용하는 것이 무엇보다. 중요하다. 아래의 4가지 대표적인 this의 사례를 통해서, 간략하게 살펴볼 수 있을 것 같다.

1. 함수선언문에서의 this
2. 메서드에서의 this
3. ES5에서의 bind 메서드
4. 함수표현식(ES6 화살표함수)에서의 this

첫째, 함수선언문에서의 this

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

콘솔에 기록되는 결과는 브라우저의 경우 window 객체, Node의 경우에는 global 객체에 this가 바인딩된다.

둘째, 메서드에서의 this

var obj = {
  greet: function() {
    console.log(this);
  }
};
obj.greet(); 

메서드란 객체에 종속된 함수를 의미한다. 메서드 내부에서의 this는 해당 함수를 호출한 주체(객체)에 바인딩됩니다. 즉 메서드가 호출할 때 자신을 소유한 객체가 명시적으로 지정되어 있기 때문에, this의 바인딩 대상은 해당 객체가 되는 것이다.

여기서 호출주체라는 말이 중요하다. 함수선언과 메서드의 호출의 주체를 아래의 코드를 통해서 살펴보자.

greet(); // 함수선언문
obj.greet(); // 메서드

함수는 명시적인 호출의 주체가 없지만, 메서드는 함수의 호출의 주체가 도트(. dot)를 통해서 연결되어 있다. 그 결과 함수는 자신을 넘어서 전역 객체에 this를 바인딩하고, 메서드는 도트(. dot)로 연결된 자신을 종속시킨 객체에 this를 바인딩하는 것이다.

함수와 메서드의 this가 바인딩 되는 가장 큰 차이점은 호출주체의 여부이다.

셋째, ES5에서의 bind 메서드

var obj = {
  greet: function() {
    console.log(this);
  }
};
var greetFunc = obj.greet.bind(obj);
obj.greet();
greetFunc();

위에서 선언한 obj.greet() === greetFunc()의 결과는 true이다. 동일한 결과가 도출된다. 위의 함수와 메서드의 예를 들면서 호출의 주체의 여부에 따라 this가 어떻게 바인딩되는지에 대해서 살펴보았다. 그러나 그러나 개발자들은 메서드가 아니라 함수를 호출의 주체 없이 사용하면서 this를 자신이 선언된 객체에 this를 바인딩하고자 고민하게 되었는데, 이러한 고민은 ES5에서 bind 메서드를 출범시몄다. 위의 코드에서 볼 수 있듯이, 명시적으로 bind 메서드드를 통해서 인자로 this가 바인딩될 변수를 명시적으로 지정할 수 있다. 이 결과에 따라서 greetFunc() 함수는 호출의 주제없이 선언되지만, this를 지정된 변수에 바인딩한다.

var obj = {
  greet: function() {
    console.log(this);
  }
};
var b = {text : "bind Method"}
var greetFunc = obj.greet.bind(b);
greetFunc()

명시적으로 객체를 바인딩하기에, 위의 같이 새로운 객체 b를 명시적으로 선언함으로 this를 b에 바인딩하는 것도 가능한 것이 ES5에서 도입된 bind 메서드의 특징이다. 이렇게 bind 메서드를 사용하면 원하는 객체에 대해 this 값을 설정할 수 있으므로, 함수를 호출하는 시점에 독립적으로 this 값을 유지할 수 있게 된다.

넷째, 함수표현식(ES6 화살표함수)에서의 this

함수선언문과 화살표함수(함수표현식)을 비교하며 this의 바인딩 대상을 탐구하는 것은 두 식의 차이를 비교하는 가장 좋은 대상이 된다.

함수선언문에서의 this의 바인딩 대상

  • 함수선언문은 함수가 선언된 시점에서 this를 상위 스코프에 바인딩한다.
  • 단독으로 호출 : 즉 호출의 주체가 없으면 언제나 this는 전역객체에 바인딩된다.
  • 생성자 함수로 호출 : 생성자 함수를 사용하여 객체를 생성함으로, this는 생성된 객체를 가리킨다.

화살표함수에서의 this의 바인딩 대상

  • 화살표 함수는 this의 바인딩 과정을 생략한다.
  • 대신, 함수가 선언된 시점에서의 렉시컬 스코프를 상속받는데, 그 결과 화살표함수의 this는 언제나 상위 스코프의 this를 참조하게 된다. 즉 함수의 호출의 상황과 상관없이 언제나 동일한 객체를 참조한다는 의미이다.
  • 함수선언문은 호출의 주체에 따라 this의 대상이 변경될 수 있지만, 화살표함수는 렉시컬 스코프에 의해 언제나 정적으로 this를 상위 스코프에 바인딩한다.

Author. Edwin.
date. 23/06/01

profile
신학전공자의 개발자 도전기!!

0개의 댓글