자바스크립트 this

2015년 08월 26일
출처 : http://html5experts.kr/archives/1668
 

자바스크립트 this는 같은 소스코드로 호출하는 형태에 따라 의미가 달라서 이를 어렵게 생각하는 경우가 있어서 이를 정리해보았습니다. JavaScript의 this는 크게 4종류가 있다는 것부터 기억하고 시작해 봅시다.

최상위 this

전역 객체를 가리킵니다.

1
2
3
4
5
6
7
8
var abc = "Kim";
window.def = " MJ";
 
console.log(this.abc + "+" + this.def);
 
(function(){
console.log(this.abc + "+" + this.def);
})();

생성자 this

만들어진 인스턴스 자신을 가르킵니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
var Abc = function Abc(msg) {
this.abc = msg;
this.method = function () {
console.log("method+" + this.abc);
}
}
 
var obj1 = new Abc("Hello");
var obj2 = new Abc("World");
 
// Hello 표시
console.log(obj1.abc);
// method+Hello 표시
obj1.method();
 
// World 표시
console.log(obj2.abc);
// method+World 표시
obj2.method();
 
// new를 안붙였기 때문에 Abc내 this는 전역 객체임
Abc("new가없음");
console.log(window.abc == "new가없음");
// method+new가없음!
window.method();

어떤 것에 소속된 this

소속된 개체를 가리킵니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
var abc = {def:"MJ"};
abc.print1 = function() {
console.log(this.def);
};
 
// MJ 표시
abc.print1();
 
var func = function() {
console.log(this.def);
};
// window.def가 참조되어 undefined
func();
 
abc.print2 = func;
// this가 abc로 변경되어 MJ표시
abc.print2();
 
// prototype시도
var Abc = function Abc(msg) {
this.message = msg;
};
Abc.prototype.print = function() {
console.log("prototype+" + this.message);
}
var obj = new Abc("Hello");
// prototype+Hello 표시
obj.print();

function#apply나 function #call등으로 강제로 변경될 때 this

jQuery를 사용하여 click이벤트등에서 this를 다시 사용할 때..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
var abc = {
 def: "MJ",
 print:function(){
 console.log(this.def);
 }
};
// 어떤 것에 소속된 this라서 MJ표시
abc.print();
 
var paramour = {def:"NTR"};
// this를 변경하여 NTR표시
abc.print.call(paramour);
 
var Abc = function Abc(msg) {
 this.message = msg;
}
Abc.prototype.print = function() {
 console.log("Love " + this.message);
}
 
var obj1 = new Abc("Dokdo");
// Love Dockdo 표시
obj1.print();
obj1.print.call({message:"korea"});
 
// this를 보호하는 방법
var ProtectedAbc = function ProtectedAbc(msg) {
 this.message = msg;
 // this 저장
 var _this = this;
 this.print = (function(fn) {
 // fn에 원래 this.print가 있음
 return function() {
 // 원래 this.print를 _this에 저장해놓은 원본 this를 사용하여 재실행
 fn.apply(_this, arguments);
 };
 })(this.print);
}
ProtectedAbc.prototype.print = function() {
 console.log("Love " + this.message);
}
 
var obj2 = new ProtectedAbc("KoreaIsland");
obj2.print.call({message:"korea"});