자바스크립트 - Vanilla JS

[자바스크립트 / Vanilla JS] this란 무엇일까 ?

Lv1_junior_dev 2022. 9. 7. 20:36

this란 ❓

this 키워드는 자신이 속한 객체 또는 자신이 생성할 인스턴스를 가리키는 자기 참조 변수(self-reference variable)이고,

this를 통해 자신이 속한 객체 또는 자신이 생성할 인스턴스의 프로퍼티나 메서드를 참조할 수 있다.

 

먼저 간단한 예를 들어보고 가자.

const myCar = {
	color: 'red',
    logColor: function() {
    console.log(this.color);
    },
  };
  
 myCar.logColor();
 // red

해당 예시에서 this 키어드가 myCar 개체를 참조한다는 것은 자명하다.

 

this의 값은 함수가 호출되는 방식에 따라 다르다. 앞의 예에서 함수는 객체의 메서드로 호출 되었다.

 

반면, 아래의 예를 보자

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

logThis();
//Window {...}

이 함수는 전역 범위에서 호출 했으므로 this는 Window 객체를 참조한다.

해당 실수를 방지하기 위해서는 strict 모드로 설정하면 방지할 수 있다.

strict 모드를 설정하려면 자바스크립트 파일의 시작 부분에 'use strict'; 를 삽입하면 된다.

 

이렇게 하면 자바스크립트에 보다 엄격한 규칙을 적용할 수 있다.

엄격한 규칙 중에는 전역 객체의 값을 Window 객체 대신에 undefined로 설정하는 규칙이 있어서,

전역 범위로 적의된 this 키워드의 값도 undefines가 된다.

 

this 값을 수동으로 설정하고자 할 때는 .bind()를 사용할 수 있다.

 

const myCar = {
	color: 'red',
    logColor: function() {
       console.log(this.color);
   	},
};

const unboundGetColor = myCar.logColor;
console.log(unboundGetColor());
//undefined

const boundGetColor = unboundGetColor.bind(myCar);
console.log(boundGetColor());
//red

위 예제의 흐름은 다음과 같다.

  • 객체 생성
  • unboundGetColor를 myCar의 logColor 메서드와 동일하게 설정
  • unboundGetColor를 호출하면 this.color를 찾으려고 하지만 전역 범위 밖의 this가 호출 되어 Window 객체가 되고 이 객체에는 color가 없기 때문에 undefined가 된다.
  • .bind()를 사용하여 boundGetColordml this 키워드가 괄호 안의 객체, 즉 여기서는 myCar를 참조함을 알린다.
  • 그리고 boundGetColor를 호출하면 의도했던 결과를 얻게된다.

this 키워드의 값을 설정하는 데 사용할 수 있는 또 다른 방법으로는 .call()과 .apply() 두 가지 방법이 있다.

두 메서드 모두 주어진 this의 값으로 함수를 호출한다는 점은 비슷하지만 받아들이는 인수가 다르다

.call()은 인수의 목록을 받고 

.apply()는 하나의 인수 배열을 받는다.


먼저 .call()을 사용하는 예제를 살펴보자

 

✔ .call()

function Car(maker, color) {
   this.carMaker = maker;
   this.carColor = color;
}

function Mycar(maker, color){
   Car.call(this, maker, color);
   this.age = 5;
}

const myNewCar = new Mycar('bmw', 'red');

console.log(myNewCar.carMaker);
// bmw

console.log(myNewCar.carColor);
// red

console.log(myNewCar.age)
// 5

.call()에 MyCar 객체를 전달하여 this.carMaker가 MyCar의 인수로 전달한 maker로 설정되도록 했다.


✔ .apply()

다음으로 .apply()를 사용한 예제를 보고 .call()과의 차이점을 확인해보자.

function Car(maker, color) {
   this.carMaker = maker;
   this.carColor = color;
}

function Mycar(maker, color){
   Car.apply(this, [maker, color]);
   this.age = 5;
}

const myNewCar = new Mycar('bmw', 'red');

console.log(myNewCar.carMaker);
// bmw

console.log(myNewCar.carColor);
// red

결과는 동일하지만, 이와 같이 .apply()는 인수 목록이 담긴 배열을 받는다.


✔.apply()와 .call()의 사용 용도

.apply()와 .call()의 사용 용도는 다음과 같다.

  • .apply()는 함수에 필요한 인수의 수를 모르거나 알 필요가 없을 때 주로 사용한다.
  • .apply()는 배열을 전달할 수 있고 배열에 포함된 원소의 수에 관계없이 함수 내부로 전달할 수 있다.
  • .call()은 인수를 개별적으로 전달 해야할 때 사용한다.

 

출처 : 모던 자바스크립트 핵심가이드 서적