[코어자바스크립트] 3. this

박현정·2021년 12월 12일
0

Javascript

목록 보기
3/4
post-thumbnail

다른 대부분의 객체지향 언어에서 this는 클래스로 생성한 인스턴스 객체를 의미하지만, 자바스크립트에서의 this는 어디서든 사용할 수 있습니다.

this는 자바스크립트에서 실질적으로 함수와 객체(메소드)의 구분하는 거의 유일한 기능입니다. 상황에 따라 this가 바라보는 대상이 달라지므로 정확한 자동 방식을 이해하지 못하면 원인을 파악해서 해결 할 수 없습니다.

this는 함수를 어떤 방식으로 호출하느냐에 따라 달라지는 방법과 명시적으로 this에 별도의 대상을 바인딩하는 방법이 있습니다.



상황에 따라 달라지는 this

자바스크립트에서 this는 기본적으로 실행 컨텍스트가 생성될 때 함게 결정됩니다. 즉 함수를 호출할 때 결정된다고 할 수 있습니다. 함수를 어떤 방식으로 호출하느냐에 따라 값이 달라지니 상황별로 정리해 보고자 합니다.

전역 공간에서의 this

전역 공간에서 this는 전역 객체를 가르킵니다. 전역 객체는 자바스크립트 런타임 환경에 따라 다른 이름과 정보를 가지고 있습니다.

브라우저 환경에서 this : window

node.js 환경에서 this : global

전역공간에서만 발생하는 특이한 성질

전역변수를 선언하면 자바스크립트 엔진은 이를 전역객체의 프로퍼티로 할당합니다. 변수이면서 객체의 프로퍼티이게 됩니다.

자바스크립트의 모든 변수는 특정객체(실행 컨텍스트의 LexicalEnvironment)의 프로퍼티로서 동작합니다. 사용자가 변수를 선언하더라도 실제 자바스크립트 엔진은 어떤 특정 객체의 프로퍼티로 인식하게 됩니다.

그런데 전역변수 선언과 전역객체의 프로퍼티 할당 사이에 전혀 다른 경우도 있습니다. 바로 ‘삭제’ 명령에서 그러합니다. 처음부터 전역객체의 프로퍼티로 할당한 경우에는 삭제가 되는 반면 전역변수로 선언한 경우에는 삭제가 되지 않습니다.

var로 선언한 전역변수와 전역객체의 프로퍼티는 호이스팅 여부 및 configurable여부에서 차이를 보입니다.

메소드로서 호출할 때 그 메서드 내부에서의 this

함수와 메소드의 차이는 독립성입니다. 함수는 그 자체로 독립적인 기능을 수행하는 반면, 메서드는 자신을 호출한 대상 객체에 관한 동작을 수행합니다. 함수로서의 호출과 메서드로서 호출은 함수 앞에 점(.)의 여부로 구분할 수 있습니다.

메서드 내부에서의 this

마지막 점 앞에 명시된 객체가 곧 this가 됩니다.

함수 내부에서의 this

this가 지정되지 않고 전역 객체를 바라봅니다.

메서드 내부함수에서의 this

내부함수 역시 이를 함수로서 호출했는지 메서드로서 호출했는지만 파악하면 this의 값을 정확히 맞출 수 있습니다.

메서드의 내부함수에서의 this를 우회하는 방법

변수를 활용하여 var self = this; 이를 사용하면 되는데, 상위 스코프의 this를 저장해서 내부함수에서 활용할 수 있게 됩니다.

ES6에서는 함수 내부에서 this가 전역객체를 바라보는 문제를 보완하고자, 실행 컨텍스트를 생성할 때 this를 바인딩 하는 과정이 없는 화살표 함수를 새로 도입해습니다.

화살표 함수를 사용하게 되면

  • 상위 스코프의 this를 그대로 활용 가능
  • 우회법이 불필요

콜백 함수 호출 시 그 함수 내부에서의 this

콜백 하무도 하무이기 때문에 기본적으로 전역객체를 참조하지만, 제어권을 받은 함수에서 콜백 함수에 별도로 this가 될 대상을 지정한 경우에는 그 대상을 참조하게 됩니다.

생성자 함수 내부에서의 this

생성자 함수 내부에서의 this는 새로 만들 구체적인 인스턴스 자신을 가르킨다.



명시적으로 this를 바인딩하는 방법

앞서 말한 규칙에 부합되지 않는다면 명시적으로 바인딩 했을 것입니다.

call메서드

Function.prototype.call(thisArg[, arg1[,arg2[, ...]]])

메서드의 호출 주체인 함수를 즉시 실행하도록 하는 명령입니다.

첫 번째 인자 : this로 바인딩

이후의 인자 : 호출할 함수의 매개변수

apply메서드

Function.prototype.apply(thisArg[,argsArray])

call메서드와 기능적으로 완전히 동일합니다.

다만 두 번째 인자를 배열로 받아 그 배열의 요소들을 호출할 함수의 매개변수로 지정한다는 차이점이 있습니다.

bind메서드

Function.prototype.bind(thisArg[, arg1[,arg2[, ...]]])

call과 비슷하지만 즉시 호출하지는 않고 넘겨 받은 this 및 인수들을 바탕으로 새로운 함수를 반환하기만 하는 메소드 입니다.

bind 메소드는 name 프로퍼티에 동사 bind의 수동태인 'bound'라는 접두어가 붙습니다. 기존의 call이나 apply보다 코드를 추적하기가 더 수월하게 됩니다.

메서드의 내부함수에서의 this를 우회하는 방법

위의 self등의 변수를 활용한 우회법보다 call, apply, bind 메서드를 이용하면 더 깔끔하게 처리 할 수 있습니다.



화살표 함수

화살표 함수는 ES6에 새롭게 도입되었습니다. 화살표 함수를 사용하면 this를 바인딩하는 과정이 제외됩니다. 접근하고자 하면 스코프체인 상 가장 가까운 this에 접근하게 됩니다.



별도의 인자로 this를 받는 경우(콜백 함수 내에서의 this)

콜백 함수를 인자로 받는 메서드 중 일부는 추가로 this로 지정할 객체(thisArg)를 인자로 지정할 수 있는 경우가 있습니다

forEach, map, filter, some, every, find, findIndex, flatMap, from

profile
FE DEVELOPER🐧

0개의 댓글