Programming Languages

[JavaScript] this 키워드 쓰임 정리 / this를 변수에 저장하는 이유

Hannana. 2024. 6. 5. 11:10
728x90
반응형

 

JavaScript의 this 키워드 이해하기

javascript에서 this 키워드는 매우 유용하지만, 동시에 혼란을 초래할 수 있는 요소이다.

this는 함수가 호출되는 방식에 따라 달라지기 때문에, 이를 올바르게 이해하는 것이 중요하다.

이번 글에서는 this가 어떤 경우에 어떻게 바뀌는지, 그리고 각 상황에서의 장단점을 설명하고자 한다.

 

1. 전역 컨텍스트에서의 this

전역 컨텍스트에서 this는 전역 객체를 참조한다. 브라우저 환경에서는 window 객체가, Node.js 환경에서는 global 객체가 된다.

console.log(this); // 브라우저에서는 window 객체, Node.js에서는 global 객체
 
  • 장점: 전역 객체에 접근할 수 있다.
  • 단점: 전역 객체를 의도치 않게 수정할 위험이 있다.

 

 

 

2. 함수 내에서의 this

기본적으로 함수 내에서 this는 전역 객체를 참조한다.

function myFunction() { 
	console.log(this); // 브라우저에서는 window 객체, strict mode에서는 undefined 
 }
 
 
  • 장점: 전역 객체에 쉽게 접근할 수 있다.
  • 단점: 함수 내부에서의 this가 의도치 않게 전역 객체를 참조하여 버그를 유발할 수 있다.

 

 

 

3. 메서드 내에서의 this

객체 내 메서드에서 this는 그 메서드를 호출한 객체를 참조한다.

const obj = {
  value: 42,
  showValue: function() {
    console.log(this.value); // 42
  }
};
obj.showValue();
 
 
  • 장점: 객체의 속성에 접근할 수 있다.
  • 단점: 메서드가 객체와 분리될 경우 this가 전역 객체를 참조하게 된다.

 

 

4. 생성자 함수 내에서의 this

생성자 함수 내에서 this는 새로 생성되는 객체를 참조한다.

function Person(name) {
  this.name = name;
}
const person1 = new Person('Alice');
console.log(person1.name); // Alice

 

  • 장점: 생성된 객체의 속성에 쉽게 접근할 수 있다.
  • 단점: new 키워드를 사용하지 않으면 전역 객체를 수정하게 된다.

 

5. 화살표 함수 내에서의 this

화살표 함수는 자신만의 this 컨텍스트를 가지지 않고, 주변(상위) 스코프의 this를 참조한다.

const obj = {
  value: 42,
  showValue: () => {
    console.log(this.value); // 전역 객체의 value (undefined)
  }
};
obj.showValue();

 

  • 장점: 상위 스코프의 this를 유지하여 콜백 함수 내에서 유용하다.
  • 단점: 자신만의 this가 없어 객체의 메서드로 사용하기 부적합하다.

 

6. bind, call, apply 메서드를 통한 this 제어

bind, call, apply 메서드를 사용하면 함수 호출 시 this를 명시적으로 설정할 수 있다.

function showValue() {
  console.log(this.value);
}
const obj = { value: 42 };
showValue.call(obj); // 42

 

  • 장점: this를 명시적으로 설정하여 유연하게 함수 호출 가능하다.
  • 단점: 코드가 복잡해질 수 있다.

 

 

추가로 알면 좋은 내용

  • 클로저와 this: 클로저 내부에서 this를 사용하면, 클로저가 정의된 스코프의 this를 유지할 수 있다.
  • 이벤트 핸들러에서의 this: DOM 이벤트 핸들러에서 this는 이벤트가 발생한 요소를 참조한다.
  • this를 변수에 저장하기: var self = this 혹은 var vm = this와 같이 this를 변수에 저장하여 클로저 내부에서 사용할 수 있다.

 


 

Q. 스코프 문제란?

:            스코프는 식별자의 유효한 범위를 말하는데, 식별자의 유효 범위와 관련한 문제가 발생한 것을 말한다.

 

 

-----------this를 변수에 저장하는 이유----------------

 

위와 같이 this는 함수가 호출된 방식에 따라 달라진다.

function MyComponent() {
  this.value = 10;
  
  setTimeout(function() {
    console.log(this.value); // undefined
  }, 1000);
}

 

위 코드에서 setTimeout 내부의 this는 MyComponent 인스턴스를 가리키지 않고,

전역 객체(브라우저에서는 window, Node.js에서는 global)를 가리킨다.

(setTimeout은 전역 객체의 메서드로 호출되기 때문)

 

따라서 setTimeout 내부에서 실행되는 콜백 함수는

일반 함수 호출로 간주되며, 이때 this는 전역 객체를 가리키게 된다.

예상한 값과 다른 값이 나오는 것이다.

 

이 문제를 해결하기 위해 var self = this를 사용한다. (변수명은 self, vm 등 상관X)

스코프 문제를 해결하기 위해 변수에 지정을 해주는 것이다.

 

function MyComponent() {
  var vm = this;
  vm.value = 10;
  
  setTimeout(function() {
    console.log(vm.value); // 10
  }, 1000);
}

 

이 코드는 var vm = this를 사용하여 this를 vm 변수에 할당하고,

이를 클로저 내부에서 사용함으로써 this의 스코프 문제를 해결하는 예시다.

 

효율성 측면

이 패턴은 성능 최적화보다는 코드를 읽고 유지보수하는 측면에서 효율적이다.

this의 컨텍스트 문제를 쉽게 해결하고, 코드의 동작을 예측 가능하게 만들어준다.

특히 비동기 함수나 콜백 함수 내부에서 this의 값이 변하는 문제를 예방할 수 있다.

 

 

결론

  • 컨텍스트 유지: this의 컨텍스트를 유지하여 함수 내부에서 this가 가리키는 객체를 명확하게 하고,
  • 가독성: 코드를 읽기 쉽게 하고, this의 변경으로 인한 버그를 예방하며
  • 유지보수성: 함수가 호출되는 방식을 신경 쓰지 않고 일관된 코드를 작성할 수 있는 장점이 있다.

따라서,

var vm = this와 같은 패턴은 JavaScript에서 this의 컨텍스트 문제를 해결하기 위한 좋은 방법이라고 할 수 있다.

 

 

 

반응형