Front-end Developer
자바스크립트의 this는 무엇일까? 본문
Javascript this를 공부해야지 해야지 하다가 드디어 공부를 하고 이렇게 정리를 해봅니다. this는 어떤 함수나 객체를 가르키게 되는데 어디서 호출되냐에 따라서 가르키는 함수 또는 객체가 달라집니다. 총 크게 6가지 경우가 있는데 어떤 경우에서 어떻게 변하는지 정리해보겠습니다.
1. 전역에서 쓴 this
전역에서 this를 호출하면 this는 Window라는 전역 객체를 가리키게 됩니다. (Node.js에서는 Global)
Window(전역 객체)는 javascript의 모든 객체, 함수, 변수들을 포함하고 있습니다.
//1. 전역에서 호출
var x = this;
console.log(x); //Window
2. 일반 함수 안에서 쓴 this
일반 함수 안에서 this가 호출이 되면 this는 함수의 주인에게 바인딩이 됩니다. 그리고 함수의 주인은 Window입니다.
var num = 0;
function addNum() {
//this는 Window를 가르킵니다.
this.num = 100;
num++;
console.log(num); // 101
console.log(window.num); // 101
console.log(num === window.num); // true
}
addNum();
this.num의 this는 window를 가르킵니다. 그래서 num은 전역변수 num을 가르키게 됩니다.
하지만, 예외인 경우가 있습니다. "use strict" 모드에서는 함수 안에서 this가 주인에게 바인딩이 안되서 Window가 되는게 아니라 undefinded가 됩니다.
"use strict";
var num = 0;
function addNum() {
this.num = 100; //ERROR! Cannot set property 'num' of undefined
num++;
}
addNum();
3. Method 안에서 쓴 this
method 안에서 할당된 this는 method를 호출한 객체로 바인딩 합니다.
var num = 0;
function showNum() {
console.log(this.num);
}
showNum(); //0
var obj = {
num: 200,
func: showNum,
};
obj.func(); //200
4. EventListener 안에서 쓴 this
EventListener안에서는 html 요소(태그, 클래스 또는 아이디)를 가리킨다.
var div = document.querySelector('#div')
div.addEventListener('click', function () {
console.log(this); //#div
});
5. 생성자 안에서 쓴 this
생성자 함수가 생성하는 객체로 this가 바인딩 됩니다.
function Man () {
this.name = 'John';
}
// 생성자로 객체 선언
var john = new Man();
// this가 Man 객체를 가리키고 있어 이름이 정상적으로 출력된다
john.name; // => 'John'
혹여나 객체를 생성할 때 생성자 함수 앞에 new를 붙이지 않는다면 this는 생성되는 객체에 바인딩되지 않는다.
function Man () {
this.name = 'John';
}
var john = Man();
john.name; // => name이 undefinded여서 error가 난다.
6. Arrow 함수에서 쓴 this
일반 함수에서는 this는 Window (전역 객체)를 바인딩하기 때문에 상위 객체 또는 함수를 바인딩 하기위해서는 Arrow function을 사용하면 된다.
일반 함수를 사용했을 때
let person = {
name: "Brad",
getName: function () {
console.log(this) // method에 this를 할당했기 때문에 person 객체에 바인딩된다.
setTimeout(function () {
console.log(this) // window 객체를 가리킨다
console.log(this.name); // undefined window객체안에 name이 없음으로!
}, 1000);
}
}
person.getName();
Arrow 함수를 사용했을 때
let person = {
name: "Brad",
getName: function () {
console.log(this) // person 객체를 가리킨다
setTimeout(() => {
console.log(this) // person객체를 가리킨다
console.log(this.name); // Brad 을 출력한다.
}, 1000);
}
}
person.getName();
7. call, apply, bind 메서드 사용
call(), apply()
call 과 apply 메서드는 첫 번째 인자를 this로 만들어주는 역할을 합니다.
function HowisThis() {
console.log(this);
}
HowisThis(); //window
var obj = {
x: great,
};
HowisThis.call(obj); //{x:great} HowisThis.apply(obj)로 써도 똑같습니다.
call 메서드의 인자안에 있는 obj가 HowisThis 함수안에 할당된 this가 obj가 됩니다.
call과 apply는 거의 같은데 차이점은 call()은 인수 목록을 받고 apply()는 인수 배열을 받는다는 차이가 있다.
function add(c, d) {
return this.a + this.b + c + d;
}
var o = {a: 3, b: 3};
// 첫 번째 인자는 'this'로 사용할 객체이고,
// 이어지는 인자들은 함수 호출에서 인수로 전달된다.
add.call(o, 6, 6); // 18
// 첫 번째 인자는 'this'로 사용할 객체이고,
// 두 번째 인자는 함수 호출에서 인수로 사용될 멤버들이 위치한 배열이다.
add.apply(o, [20, 10]); // 36
bind()
ES5에서 도입이 되었는데, bind() 메서드 안에 obj를 호출하면 this는 원본 함수를 가진 새로운 함수를 생성하고 bind는 한 번만 동작을 합니다.
function f() {
return this.a;
}
var g = f.bind({a: 'Brad'});
console.log(g()); // Brad
var h = g.bind({a: 'Daeho'}); // bind는 한 번만 동작함!
console.log(h()); // Brad
var o = {a: 29, f: f, g: g, h: h};
console.log(o.a, o.f(), o.g(), o.h()); // 29, 29, Brad, Brad
참고자료
자바스크립트 MDN this - Mozilla
(JavaScript) 자바스크립트의 this는 무엇인가? -ZeroCho Blog
[JS] 자바스크립트에서의 this :: nana_log - 나나
'JavaScript' 카테고리의 다른 글
JavaScript : script async 와 defer, 'use strict' (0) | 2021.02.22 |
---|---|
JavaScript_모멘텀 project [이름 삭제하는 button 만들기] (0) | 2021.02.15 |
Ajax_ API 데이터 값 가져오기 (0) | 2021.02.14 |
JavaScript : [ Variable, Array, Object, Function] (1) | 2021.02.04 |