this

내가 국민학교 2,3학년때 (1992년정도?) 3-4명이 그룹을 지어 1조를 이뤄 매 주 각 집으로 로테이션하면서 영어선생님을 모시고 학습하는게 유행이었다. 그때 핵심 자료는 영어 비디오였다. (지금은 찾아보기도 힘든 비디오 테이프이지만..) 다른 건 기억이 하나도 나지 않지만, 요상한 동물이 나와 요상한 영어 노래를 부르던 장면은 어렴풋이 기억이 난다.(이 동물은 과연 무엇이었을까?)

"This is a banana" , "This is an apple" 노래와 함께 여러 과일들을 영어로 소개해줬다. 이 때 배웠던 멜로디와 "This is ..." 문장은 내 머릿속에 깊숙히 새겨져 있다.한글로 해석하면 단순히 '이것'이라고 말할 수 있지만 영어에서는 좀 더 포괄적으로 사용되고 있는 거 같다.

그렇다면 프로그래밍에서 this란 단어는 어떤 역할을 하는걸까? 아니 더 작게 프로그래밍 > 자바스크립트에서 this란 어떤 역할을 알아보자.

techsith 유튜브 - Javascript this keyword explained | in Gloable Scope, Object, Function, Prototype, Method, Class 초반에 this에 대한 재미난 설명이 있었다.

예를들어 JJuice의 집은 제주도 제주시 제주동에 위치하고 35년전에 지어졌다. 오래된 집인만큼 수도관에서 물이 새고 보일러도 고장나 수리가 필요하다.

수리업체에 전화해서 JJuice의 집에 대해 정의를 한 후 (주소 및 기타 사항등) '이 집의 수도관은 고장났어요..' 라고 말한다. 여기서 '이 집'이라고 하는 건 바로 'this'라고 대신 사용할 수 있다.

우리가 매 번 '제주도 제주시 제주동에 위치한 35년된 JJuice가 주인인 집은 수도관이 고장났고요,' / '제주도 제주시 제주동에 위치한 35년된 JJuice가 주인인 집은 보일러가 고장났어요.' 라고 말하지 않는다. 이 집, 즉 'this' 단어 하나로 줄여서 말한다.

자바스크립트에서도 this도 위와같은 역할을 하는게 아닐까? 모든 것이 객체로 이루어진 자바스크립트인만큼 '제주도 제주시 제주동에 위치한 35년된JJuice' 의 객체에 '고장난 보일러'란 프로퍼티가 있다면 이 객체의 정보를 수리업체 변수에 알려줄때 this라는 키워드를 이용해 this.고장난 보일러=true 정보를 전달해 줄 수 있는 것이다.

자바스크립트의 this는 참으로 매력?!적이라고 할 수 있다. (솔직하게 나에겐 자바스크립트의this 매력적이라기도 보다 무쟈게 헷갈린다.) 이 this는 상황에 따라 유동적으로 변하기도 하고 여러가지 방법?!을 이용해 this에 내가 원하는 객체도 지정할 수 있다. 이 부분에 대해서 좀 더 자세히 알아보기로 하자.

상황별 this가 가르키는 것은? (브라우저 환경)

■ Global 영역에서의 this

자 구글 크롬창 > 개발자 도구 > 콘솔 란에 들어가서 쳐보자.

console.log('this는 누구일까요?:' + this);

바로 [object Window]라고 나온다.
그 이유는 브라우저 환경에서는 최상위 객체가 window이고 window객체안에 'console'이라는 프로퍼티가 존재하기 때문이다.

node환경에서는 최상위 객체가 global object이다.

<😮JJuice 실험실>
① this에 등록하기 / window에 등록하기 / 변수로 등록하기

this.house = '제주도 제주동 제주시 35년된 JJuice집';
window.home = '제주도 제주동 제주시 35년된 JJuice집';
const jjuiceHouse = '제주도 제주동 제주시 35년된 JJuice집';

console.log(house); //'제주도 제주동 제주시 35년된 JJuice집'
console.log(home); //'제주도 제주동 제주시 35년된 JJuice집'
console.log(jjuiceHouse); //'제주도 제주동 제주시 35년된 JJuice집'

console.log(this.house); //'제주도 제주동 제주시 35년된 JJuice집'
console.log(this.home); //'제주도 제주동 제주시 35년된 JJuice집'
console.log(this.jjuiceHouse); // undefined

위의 코드에서 this 가 곧 window이다.

this.house=... 의 의미는 window객체에 house프로퍼티에 값을 등록하는 것이다.

const jjuiceHouse = ...의 의미는 windows객체에 jjuiceHouse프로퍼티로 등록하는게 아닌 처음 코드를 실행하는 순간 생성되는 전역 컨텍스트객체에 variable 프로퍼티에 등록하는 것이다. 그렇기 때문에 console에 this.jjuiceHouse 결과값이 undefined가 나온다.

'전역 컨텍스트 객체': {
	'변수 객체' : {
		variable: ['jjuiceHouse'],
	},
	'스코프 체인': ['전역 변수객체'],
	'this': window,
}

만약 const가 아닌 var jjuiceHouse로 변수를 선언했다면 this.jjuiceHouse=...결과값이 undefined가 아닌 정상적인 값이 출력된다. (var로 선언된 변수는 window객체에 프로퍼티로 값이 등록된다라는 의미)
실제 코딩하는데 있어서 this. or window. 이런식으로 프로퍼티값을 등록하는 경우는 거의 없다고 한다니 이 정도만 하고 다음 내용으로 넘어가보자.

■ 함수에서의 this가 가르키는 것은?

보통 밑에서의 코드처럼 함수를 선언하고 실행하게 되는데,

function callRepairShop() {
	console.log(this); 
}
callRepairShop();//window

여기서의 this도 위의 Global 영역에서와 마찬가지로 window를 가르킨다.

<🙄왜 그런걸까?>

● 위에서 const jjuiceHouse=.. 전역컨텍스트 객체 > variable 프로퍼티에 등록되는거처럼 전역에서 선언된 함수 function callRepairShop(){}역시 전역컨텍스트 객체 > variable 프로퍼티에 등록되는 것이다.

● 예를 들어 const jjuiceHouse=..function callRepairShop() {}가 Global영역에 순서대로 선언되었다고 가정해보자.

const jjuiceHouse = '제주도 제주시..';
function callRepairShop() { }

● 위의 코드를 전역 컨텍스트 객체로 표현해보자.

'전역컨텍스트': {
	'변수 객체': {
		variable: [ {jjuiceHouse:'제주도..'}, {callRepirShop:'function'}]
	},
	'스코프 체인': ['전역 변수객체'],
	'this': window
}

'callRepairShop()'함수를 품고 있는 건 바로 '전역 컨텍스트'이고 이 '전역컨텍스트'의 this는 window를 가르킨다.

자바스크립트에서는 '전역 컨텍스트' 뿐만 아니라 '함수 컨텍스트'가 존재하는데, 바로 이 '함수 컨텍스트'는 함수가 호출할 때 컨텍스트가 생성된다. (즉 함수가 실행되는 순간 '함수 컨텍스트'가 생성되고 아래의 코드처럼 this가 누구를 가르키게 되는지 결정되는 것이다.)

//callReairShop(); 함수 실행시
'callRepairShop함수 컨텍스트': {
	'변수객체': { variable: null },
       '스코프체인': {['callRepairShop변수객체','전역 변수 객체']},
	 this: window
}

⚡기억해두면 좋을 내용 : '함수 컨텍스트'는 함수 실행시 생성되지만 '스코프체인'은 함수 선언시 범위가 지정된다. ->'렉시컬 스코프'라고도 불린다.

<😮JJuice실험실>
① 함수안에 내부함수를 선언하고 실행한 상황이라면?

function outer() {
	console.log('outerFunction' + this);
	function inner() {
		console.log('innerFunction' + this);
	}
	inner();
}
outer();

➡outer,inner 함수 전부 this는 window를 가르킨다. ( 'this에 전역 객체를 바인딩시킨다' 라는 표현이 더 확실하지만 내가 쉽게 이해하기 위해서 'window를 가르킨다'라는 표현을 사용했다. )

② 'use strict'엄격모드 상황이라면?

'use strict';
function fn() {
	console.log('outerFunction:' + this);
}
fn();

➡this는 undefined이다.

엄격모드에서는 this가 정의되지 않았다. 왜 그런걸까?

■ 메서드에서의 this가 가르키는 것은?

자바스크립트 객체에는 다양한 프로퍼티 뿐만 아니라 메서드들을 등록하는게 가능하다.

profile
코딩초보 JJu의 좌충우돌 Coding Story-JJuice

0개의 댓글