- JavaScript의
this는 런타임 때, 실행할 때 this가 가리킬 때 변경이 된다. - 상황에 따라서
this가 달라지기 때문에 디버깅을 통해 알아 내야 한다.
대표적인 상황 This
1. function
function code() {
return this;
}
code(); //window
window : 최상위 오브젝트로 전역객체이다.
function code() {
a = 'this is a';
console.log(a);
}
code(); // this is a
console.log(window.a); // this is a
console.log(this.a); // this is a
2. function - constructor
- 객체지향적인 언어에서는 클래스를 만들고 클래스를
new키워드로 부를 때는 인스턴스 즉객체를 반환한다. JavaScript도 유사하게 동작한다. new가 객체를 만들어서 반환해 준다.
function Code() {
this.name = 'this is name';
}
new Code(); // Code {name: "this is name"}
3. object literal
var obj = {
code : function() {
return this; // 여기의 `this`는 `obj`를 가리킨다
}
}
obj.code() //object (obj)
var obj = {
code : function() {
this.printCode();
},
printCode : function() {
console.log('printCode!');
}
}
obj.code(); // pprintCode!
4. async(비동기)
this가 헷갈리는 큰 이유는async 로직때문이다. (비동기 상황에 문제가 된다)obj.code()실행하면code함수가 실행이 되고 그 안에 있는setTimeout함수가 1초뒤에 실행.setTimeout함수는code함수가 실행 될때 실행되어 보이지만setTimeout 콜백함수로써EventQueue라는 공간에 보관되어 있다가 임의로 시작된다. 즉,obj객체와code함수와 전혀 상관없이 나중에 실행되는 함수.
var obj = {
code : function() {
setTimeout(function() {
this.printCode();
},1000);
},
printCode : function() {
console.log('hello obj!!!');
}
}
obj.code(); // 1초뒤에 `Uncaught TypeError: this.printCode is not a function`
5. bind 메서드를 활용해 해결가능
setTimeout안에 있는 함수는 다른 곳으로 빠져 나와 실행이 된다.obj객체,code함수와 전혀 상관없는EventQueue에서 실행되는 함수이기 때문에 여기에this는 실행 컨텍스트인obj객체를 벗어나기 때문this를 내가 원하는 실행 콘텍스트로 지정하려면bind매소드를 사용하면this를 지정할 수 있다 =>bind(this)
(function() {
this.printCode();
},1000);
var obj = {
code : function() {
setTimeout(function() {
this.printCode();
}.bind(this),1000); // bind로 지정한 `this`는 `obj객체`를 가리킨다
},
printCode : function() {
console.log('hello obj!!!');
}
}
obj.code(); // 1초뒤에 `hello obj!!!` 실행
6. debugging
- debugger로 그때그때의 this를 확인하는 것이 this를 이해하고 문제를 해결하는 좋은 방법이다.
var obj = {
code : function() {
setTimeout(function() {
debugger;
this.printCode(); // this : Window
},1000);
},
printCode : function() {
console.log('hello obj!!!');
}
}