Frontend/JavaScript

[JavaScript] this

Rayched 2023. 10. 25. 16:40
목차
1. this란?
 ① this
 ② this.(Key)와 '객체 변수'.(Key) 비교
2. JavaScript에서의 this
3. Reference

1. this란?

이전 게시글에서 메서드를 추가하고 사용하는 것을 다뤘지만

객체 메서드가 객체 Property를 참조할 수 있게 하는 방법에 대해서는 다루지 않았었다.

그러므로 이번에 다룰 것은 메서드가 객체 Property를 참조하려고 할 때 쓸 수 있는 'this' 키워드에 관한 것이다.


① this

//this 예제

const Person = {
    name: "John",
    Hello(){
    	console.log(`안녕하세요. 저는 ${this.name}입니다.`);
    }
};

Person.Hello();

객체 메서드에서 'this'는 아래와 같이 입력하는 것으로 객체 Property를 참조할 수 있다.

this.(Key);

여기서 'this'가 가리키는 것은 현재 객체를 가리키기 때문에

위와 같이 작성하면 현재 객체의 (key)라는 Property를 참조하게 된다.

실제로 this가 현재 객체를 가리키는지 파악하기 위해서 예제를 하나 더 준비해 봤다.

 

이번에는 외부에서 만든 InfoPrint 함수를 Person1, Person2 객체에 메서드로 추가하고, 실행하는 예제이다.

//예제 2

function InfoPrint(){
    let Name = this.name;
    let Age = this.age;
    
    console.log(`이름 : ${Name}`);
    console.log(`나이 : ${Age}`);
}

const Person1 = {
    name: "홍길동",
    age: 25
};

const Person2 = {
    name: "John",
    age: 30
};

Person1.Hello = InfoPrint;
Person2.Hello = InfoPrint;

Person1.Hello();
Person2.Hello();

예제 2 실행 결과, this가 현재 객체를 가리킨다는 것을 알 수 있다.

Person1, Person2 객체에 InfoPrint 함수를 메서드로 추가하고

이를 실행했을 때, 해당 함수가 각 객체의 name, age Property를 참조했다는 것을 파악할 수 있다.


② this.(Key)와 '객체 변수'.(Key) 비교

 

'this'가 어떤 역할을 하는지 알았지만 한 가지 궁금증이 생겼다.

그것은 JavaScript에서 객체 Property로 접근할 때 '점 표기법'을 통해서도 접근이 가능하기에

굳이 'this.(Key)'와 같이 입력해서 메서드에서 객체 Property로 접근할 필요가 있냐는 것이다.

 

객체 메서드에서 객체 Property로 접근할 때 '점 표기법'을 사용하면

예기치 못한 Error를 마주할 수 있기 때문에 위의 방법을 사용하지는 않는다고 한다.

 

그러면 앞에서 제시한 예제 2의 소스코드에서 'this.(Key)'로

작성된 부분을 전부 '객체변수.(Key)'로 수정해 보도록 하자.

//예제 3
//this.(Key)를 객체변수.(Key)로 수정

function InfoPrint(){
    let Name = Person1.name;
    let Age = Person1.age;
    
    console.log(`이름 : ${Name}`);
    console.log(`나이 : ${Age}`);
}

function InfoPrint2(){
    let Name = Person2.name;
    let Age = Person2.age;
    
    console.log(`이름 : ${Name}`);
    console.log(`나이 : ${Age}`);
}

const Person1 = {
    name: "홍길동",
    age: 25
};

const Person2 = {
    name: "John",
    age: 30
};

Person1.Hello = InfoPrint;
Person2.Hello = InfoPrint2;

Person1.Hello();
Person2.Hello();

InfoPrint 함수를 그대로 Person2 객체의 메서드로 추가한 후, 해당 메서드를 실행하면

Person2의 name, age의 값이 아니라 Person1의 name, age Property가 출력될게 뻔하기 때문에

 

InfoPrint 함수 내부에서 선언한 변수 Name, Age에서 객체 명만 수정한 (Person1 → Person2)

InfoPrint2 함수를 Person2 객체의 메서드로 추가해 주도록 하자.

 

그리고 Person1, Person2 객체의 Hello 메서드를 실행하면

예제 2와 같은 결과가 console 창에 출력되는 것을 확인할 수 있다.

 

물론 변수 값 외에는 외형적으로 전혀 다르지 않은 함수가 두 개나 존재하고

객체의 개수가 늘어날 때마다 변수 값만 다른 중복된 기능을 가진 함수도 늘려야 된다는 것은

너무나도 번거롭고 귀찮은 작업이 아닐 수가 없다.

 

따라서 점 표기법을 활용해서 객체 메서드에서 Property로 접근하는 방식은 적절하지 않다.

그냥 'this.(Key)'로 입력해서 객체 Property로 접근하도록 하자.


2. JavaScript에서의 this

JavaScript에서 'this'는 다른 언어들처럼 현재 객체를 가리킨다는 점은 같지만

다만 JavaScript에서 'this'는 다소 다르게 작동을 한다는 차이점을 가지고 있다.

 

JavaScript에서 'this'가 다른 언어와 비교해서 어떤 부분이 다른지 아래 예제들을 통해서 확인해 보자.

//'this'를 return하는 TestFunc

class Main {
	public static String TestFunc(){
		return this; //error
	}
	
	public static void main(String[] args) {
		TestFunc();
	}
}

Java에서의 'this'는 class를 기반으로 생성된 instance, 현재 객체를 가리킨다.

즉, 위와 같이 사용하는 것은 잘못된 사용 방식이므로 당연히 error가 발생한다.

 

다만 JavaScript에서는 전혀 다른 결과가 나오게 된다.

//'this'를 return하는 TestFunc

function TestFunc(){
	return this;
}

TestFunc(); //??

예제 실행 결과

위의 예제 소스코드를 개발자 콘솔에서 실행했을 때

window 객체가 return 된 것을 위의 예제 실행 결과를 통해 알 수 있다.


JavaScript에서 'this'는 호출된 시점에 따라 가리키는 객체가 달라지게 된다.

객체 메서드에서 'this'를 사용했다면 해당 키워드는 현재 객체를 가리키지만

객체 메서드가 아닌, 전역 함수에서 'this'를 사용했다면 해당 키워드는 전역 객체를 가리키게 된다.

 

여기서 전역으로 사용한 'this'가 가리키는 전역 객체는 작성한 환경에 따라 달라진다.

웹 브라우저에서 전역 객체는 'window', Node.js 상에서 전역 객체는 'global'이다.

(전역 객체에 대해서는 나중에 공부를 더 하고 나서 다뤄보도록 하겠다.)

("일단은 이런 게 있다."하고 넘어가도록 하자.)

 

예제 소스코드를 크롬 개발자 도구에서 실행했기 때문에

전역으로 사용한 'this'가 가리키는 객체는 window 객체이다.

 

즉, Java로 작성했던 코드와는 달리 JavaScript의 'this'는 전역으로 사용해도

참조하는 객체가 있기 때문에 Error가 발생하지 않는 것이다. (Web Browser == window 객체)

 

//전역으로 사용한 this가 window 객체를 참조하는 것이
//참인지 검증하는 예제

function TestFunc(){
	return this;
}

let A = window;
let B = TestFunc();

console.log("전역으로 사용한 this가 window 객체를 참조하는 지 검증");
console.log(A == B); //??
console.log(A === B); //??

window 객체를 참조하는 변수 A와, TestFunc 함수를 할당받은 변수 B를 비교, true가 return 됐다.

이를 통해서 정말로 전역으로 사용한 'this'가 전역 객체, window 객체를 참조한다는 것을 알 수 있다.


3. Reference

참고한 자료

모던 JavaScript - 메서드와 this
MDN JavaScript - this

수정 내역

2023.10.25 본문 작성 완료