자바스크립트 상황에 따라 다른 this

·2022년 6월 20일
0

this는 자바스크립트에서 가장 혼란스러운 개념 중 하나이다.
이전에 class를 익히려고 할때 이 this때문에 많이 어려움을 겪었는데, 어렴풋이 이해하고 넘어갔던 this의 개념을 코어자바스크립트 책을 통해 확실히 정리해보려고 한다.


this란

객체지향 언어에서 this는 보통 생성한 인스턴스 객체를 의미한다. 하지만 자바스크립트에서의 this는 어디서든 사용할 수 있으며 상황에 따라 달라지게 된다. 또한 실행 컨텍스트가 생성될 때 결정되며 함수와 객체의 구분한 자바스크립트에서 this는 실질적으로 이 둘을 구분하는 거의 유일한 기능이다.

전역 공간에서의 this

전역공간에서 this는 전역 객체를 가리킨다. 전역객체는 자바스크립트 런타임 환경에 따라 다른 이름과 정보를 가지고 있다.
브라우저 환경에서 전역객체는 whindow이고 Node.js는 global이다.

console.log(this) // {alert:f(),atob:f(),blur:f().....}
console.log(this === window) // true

전역 변수와 전역 객체

전역변수를 선언하면 전역객체의 프로퍼티로 할당된다.

var a = 1
console.log(window.a) //1
console.log(this.a)//1

대부분의 경우에선 window의 프로퍼티로 직접 할당 할 때 전역변수와 동일하게 동작한다. 하지만 삭제 명령은 다르게 작동한다.
이는 사용자가 의도치 않게 삭제하는 것을 보호하기 위함이라고 해석된다. 즉 전역변수를 선언하면 전역객체의 프로퍼티로 할당이 되나 해당 프로퍼티의 configurable(변경/삭제가능성) 속성이 false가 된다.

var a = 1
delete window.a // false
delete a // false

window.b = 2
delete window.b // true
delete b // true

메서드 내부에서의 this

어떤 함수를 함수로서 호출할 경우에는 this가 지정되지 않는다.
실행 컨텍스트를 활성화 할 당시에 this가 지정되지 않은 경우 this는 전역 객체를 바라보게 된다.
그러나 객체의 메서드로써 호출된 함수는 해당 객체를 가리키게 된다

var obj1 = {
  outer:function(){
  	console.log(this) 
    var innerFunc = function(){
    console.log(this)
    }
    innerFunc() // window - 일반 함수로 호출됨 ,
    
    var obj2={
      innerMethod:innerFunc
    }
    obj2.innerMethod() //  {innerMethod:f} - 메서드로써 호출됨
  }
}
obj1.outer() // {outer:f} obj1의 메소드로 호출됨.

콜백함수의 this

[1,2,3].forEach(function(x){
	console.log(this) // 전역객체
})

var div = document.body.querySelector('div')
div.addEventListener('click',function(){
	console.log(this) // div
})
 

forEach는 콜백함수를 호출할 때 this를 지정하지 않음. 그러나 addEventListner은 호출할 때 자신의 this를 상속하도록 정의되어있음.
따라서 콜백함수에서의 this는 무조건 이거다 라고 정의할 수 없음.

생성자 함수 내부에서의 this

프로그래밍적으로 '생성자'는 구체적인 인스턴스를 만들기 위한 틀이다.
자바스크립트는 함수에 생성자로서의 역할을 함께 부여했다.
생성자 함수를 호출하면 생성자의 prototype 프로퍼티를 참조하는 proto 라는 프로퍼티가 있는 인스턴트를 만들고 준비된 공통 속성 및 개성을 해당 객체(this)에 부여한다.

var Cat = function(name,age){
	this.name = name
	this.age = age
}

var choco = new Cat('야옹이',5) // {name:'야옹이',age:5}
choco.name //야옹이
choco.age // 5

참고문서

코어자바스크립트를 읽고 정리한 글입니다.

profile
나 예인쓰, 응애인디

0개의 댓글