
ZeroCho 블로그의 '자바스크립트의 this는 무엇인가?' 글을 참조하여 작성하였습니다.
크롬의 콘솔창에서 this;를 입력하면 Window 객체를 가리키게 된다.

function a() {
console.log(this);
};
a(); // Window 객체

기본적으로 Window 객체를 가리키는 것을 알 수 있다.
let obj = {
a: function() {
console.log(this);
}
};
obj.a(); // obj
객체 메서드 안의 this는 해당 객체를 가리킨다.
이는 객체의 메서드를 호출할 때 this를 내부적으로 바꾸어 주기 때문이다.
하지만 다음과 같이 하면 결과가 달라진다.
let a2 = obj.a;
a2(); // window 객체
호출을 할 때 호출하는 함수가 객체의 메서드인지 그냥 함수인지가 중요하다.
a2는obj.a를 꺼내온 것이기 때문에 더이상 obj의 메서드가 아니다.
함수 메서드 삼총사 bind, call, apply 그리고 arguments 글을 참조하도록 하자.
명시적으로 this를 바꾸는 함수 메서드 삼총사 bind, call, apply를 사용하면 this가 Window 객체가 아닌 다른 객체를 가리키도록 할 수 있다.
let obj2 = { c: 'd' };
function b() {
console.log(this);
}
b(); // Window
b.bind(obj2).call(); // obj2
b.call(obj2); // obj2
b.apply(obj2); // obj2
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.sayHi = function() {
console.log(this.name, this.age);
}
생성자 함수도 함수이므로, new를 사용하지 않고 호출하면
Person('frenchkebab', 26);
console.log(window.name, window.age); // frenchkebab 26
this.name은 window.name,
this.age는 window.age가 되어버린다.
이를 막으려면 new 예약어를 사용해야 한다.
let hero = new Person('hero', 33); // Person {name: 'Hero', age: 33}
hero.sayHi(); // Hero 33
이렇게 new를 붙이면 this가 생성자를 통해 생성된 인스턴스가 된다.
이렇게 실수로
new를 붙이지 않는 문제를 막는 장치인class가 ES6에 추가되었다.
document.body.onclick = function() {
console.log(this); // <body>
얘는 그냥 함수인데 this가 window가 아니라 <body>이다.
bind한 것도 아니고new를 붙인 것도 아니고그럼 누가 바꾼걸까?
바로 이벤트가 발생할 때, 내부적으로 this가 바뀐 것이다.
내부적으로 바뀐 것이기 때문에 외우라고 한다...........
$('div').on('click', function() {
console.log(this);
});
이러한 제이쿼리 코드의 경우 this는 클릭한 div가 된다.
내부적으로 function을 호출할 때 this를 그렇게 바꾸어 버린다.
이것도 어쩔 수 없이 외우라고 한다.....
$('div').on('click', function() {
console.log(this); // <div>
function inner() {
console.log('inner', this); // inner Window
}
inner();
});
이 경우에는 미쳐버리게도 this가 window 객체를 가리킨다.
함수의 this는 기본적으로 window라는 원칙을 충실히 따른 것이다.
click 이벤트 리스너가 내부적으로 this를 바꾸었음에도 명시적으로 알리지 않은 것이 문제이다.
이를 해결하기 위해서는,
$('div').on('click', function() {
console.log(this); // <div>
var that = this;
function inner() {
console.log('inner', that); // inner <div>
}
inner();
});
이렇게 변수에 this를 저장해 주어야 한다.
혹은 ES6 화살표 함수를 사용하면 가능하다.
$('div').on('click', function() {
console.log(this); // <div>
const inner = () => {
console.log('inner', this); // inner <div>
}
inner();
});
ES6 화살표 함수는
this로 window객체 대신 상위 함수의this를 가져온다. (이 경우<div>)
this는 기본적으로 window이다. 하지만 아래의 경우this가 바뀐다.
- 객체 메서드
bind,call,applynew그리고 이벤트리스너 등도
this를 내부적으로 바꿀 수 있으니this를 확인해 보아야 한다.또한, 내가 선언한 function의
this는 항상 window라는 것을 잊지 말 것!