[Javascript] this

Subin·2020년 4월 2일
0

함수와 객체(메서드)의 구분이 느슨한 자바스크립트에서 this는 실질적으로 이 둘을 구분 하는 거의 유일한 기능이다. 상황별로 어떻게 달라지는지, 왜 그렇게 되는지 알아보자.

상황에 따라 달라지는 this

자바스크립트에서 this는 기본적으로 실행 컨텍스트가 생성될 때 함께 결정된다. 실행 컨텍스트는 함수를 호출할 때 생성되므로, this는 함수를 호출할 때 결정된다.

1. 전역에서 this

전역에서 this는 전역 객체를 가르킨다. 개념상 전역 컨텍스트를 생성하는 주체가 바로 전역 객체이기 때문이다. 브라우저 환경에서는 window이고 Node.js 환경에서는 global이다.

예) 전역 공간에서 this

//브라우저 환경
console.log(this === window); // true
// Node.js 환경
console.log(this === global); // true

예) 전역변수와 전역객체

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

전역공간에서 선언한 변수 a에 1을 할당할 때, window.a와 this.a 모두 1이 출력된다. 그 이유는 자바스크립트에서 전역변수를 선언하면 자바스크립트 엔진은 이를 전역객체의 프로퍼티로 할당하게 되기 때문이다. 스코프 체인에서 a를 검색하다가 가장 마지막에 도달하는 전역 스코프의 전역객체에서 해당 프로퍼티 a를 발견해서 그 값을 반환하기 때문이다. window나 this 없이 a로도 값을 반환하는 이유는 단순히 window와 this를 생략할 수 있기 때문이다.

2. 함수와 메서드에서 this

함수를 실행하는 방법은 여러 가지가 있는데, 가장 일반적인 방법은 함수로 호출하는 경우와 메서드로 호출하는 경우다. 이 둘의 유일한 차이는 독립성에 있다. 함수는 그 자체로 독립적인 기능을 수행하는데 메서드는 자신을 호출한 대상 객체에 관한 동작을 수행한다. 자바스크립트는 상황별로 this 키워드에 다른 값을 부여해 이를 구분한다.

예) 함수 호출, 메서드 호출

var func = function(x) {
  console.log(this, x);
}
func(1); // Window{...} 1

var obj = {
  obj2: func
}
obj.obj2(2); // { obj2: f} 2

func를 그대로 호출할 때 this로 전역객체로 Window를 출력한다. obj의 메소드로 호출을 할 때, this는 obj2가 된다. 함수 호출과 메서드 호출을 구별하는 간단한 방법은 함수 앞에 ' . '이 있느냐에 달려있다. obj2 앞에 점이 있으니 메서드로 호출된 것이고, 여기서 this는 obj2가 된다.

3. 콜백 함수에서 this

예) 콜백함수 내부의 this

setTimeout(function() {console.log(this);}, 300); // Windonw {...}

[1,2,3,4,5].forEach(function(x) {
  console.log(this, x);
}); //  Window {...} 1, Window {...} 2, ... Window {...} 5

document.body.innerHTML += '<button id="a">클릭</button>';
document.body.querySelector('#a')
	.addEventListener('click', function(e) {
  		console.log(this, e);
	}); // MouseEvent {...}

setTimeout 함수와 forEach 메서드는 그 내부에서 콜백 함수를 호출할 때 대상이 될 this를 지정하지 않는다. 따라서 콜백 함수 내부에서의 this는 전역객체를 참조한다. addEventListener 메서드는 콜백 함수를 호출할 때 자신의 this를 상속하도록 정의돼 있다. 그렇기 때문에 메서드명의 점(.) 앞부분이 곧 this가 된다.

콜백함수에서 this는 '무조건 이거다'라고 정의 할 수 없다. 제어권을 가진 함수(메서드)가 콜백 함수에서 this를 무엇으로 할지 결정하고, 특별히 정의하지 않으면 기본적으로 함수와 마찬가지로 전역객체를 바라본다.

4. 생성자 함수 this

자바스크립트는 함수에 생성자로서의 역할을 함께 부여했다. new 명령어와 함께 함수를 호출하면 해당 함수가 생성자로서 동작하게 된다. 그리고 어떤 함수가 생성자 함수로서 호출된 경우 내부에서 this는 곧 새로 만들 구체적인 인스턴스 자신이 된다.

생성자 함수를 호출하면 우선 생성자의 prototype 프로퍼티를 참조하는 __ proto __라는 프로퍼티가 있는 객체를 만들고, 미리 준비된 공통 속성 및 개성을 해당 객체(this)에 부여한다.

예) 생성자 함수

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

var kim = new Student('철수', 19);
var park = new Student('지성', 22);

console.log(kim, park);
/*
Student {name: "철수", age: 19} 
Student {name: "지성", age: 22}
*/

Student란 변수에 익명 함수를 할당하고, 이 함수 내부에서 this에 접근해 name, age 프로퍼티에 가각 값을 대입한다. this는 각각 kim과 park을 가르킴을 알 수 있다.

출처
코어 자바스크립트 __ 정재남 지음

profile
정확하게 알고, 제대로 사용하자

0개의 댓글