JavaScript에서 this가 바인딩할 객체는 함수가 선언할 때 정적으로 결정되는 것이 아니다.
함수를 호출할 때 함수의 호출 방식에 따라 바인딩할 객체가 동적으로 결정된다.
1. 함수의 this
기본적으로 this는 전역 객체를 바인딩한다.
전역 객체 (Global Object)
전역 객체는 모든 객체의 유일한 최상위 객체를 의미한다.
- Browser-side → window 객체
- Server-side → global 객체
// browser side
this === window // true
// server side (node.js)
this === global // true
내부 함수
내부 함수는 일반 함수, 메서드, 콜백 함수 어디에서 선언되었든 관계없이 this가 전역 객체를 바인딩한다.
function foo() {
console.log("foo's this: ", this); // window
function bar() {
console.log("bar's this: ", this); // window
}
bar();
}
foo();
메서드의 내부 함수
메서드의 내부 함수인 경우도 this는 외부 함수가 아닌 전역 객체를 바인딩한다.
var value = 1;
var obj = {
value: 100,
// 메서드의 this: 메서드를 호출한 객체
foo: function() {
console.log("foo's this: ", this); // obj
console.log("foo's this.value: ", this.value); // 100
// 메서드의 내부 함수의 this: 전역 객체
function bar() {
console.log("bar's this: ", this); // window
console.log("bar's this.value: ", this.value); // 1
}
bar();
}
};
obj.foo();
콜백 함수
콜백 함수의 경우 this는 전역 객체를 바인딩한다.
var value = 1;
var obj = {
value: 100,
foo: function() {
setTimeout(function() {
console.log("callback's this: ", this); // window
console.log("callback's this.value: ", this.value); // 1
}, 100);
}
};
obj.foo();
2. 메서드의 this
함수가 객체의 프로퍼티일 때 함수는 메서드로 호출된다.
이때 메서드의 this는 해당 메서드를 소유한 객체, 즉 해당 메서드를 호출한 객체를 바인딩한다.
var obj = {
a: function() { console.log(this); },
};
obj.a(); // obj
단 다음의 경우에선 this는 전역 객체를 가리킨다.
a2
는 obj.a
를 꺼내온 것이기 때문에 더 이상 obj
의 메서드가 아니기 때문이다.
var a2 = obj.a;
a2(); // window
3. 생성자 함수의 this
JavaScript의 생성자 함수는 말 그대로 객체를 생성하는 역할을 한다.
기존 함수에 new 연산자를 붙여 호출하면 해당 함수는 생성자 함수로 동작한다.
만약 new를 사용하지 않고 그냥 호출한다면 this는 전역 객체를 가리킨다.
new를 붙이면 this는 생성자를 통해 생성된 인스턴스를 가리킨다.
// 생성자 함수
function Person(name) {
this.name = name;
}
var me = new Person('Lee');
console.log(me); // this: me 인스턴스
var you = Person('Kim');
console.log(you); // this: window
4. 이벤트 리스너의 this
이벤트 리스너에서 this는 이벤트를 발생시킨 객체가 된다.
document.body.onclick = function() {
console.log(this); // <body>
}
5. 화살표 함수의 this
화살표 함수의 this는 상위 스코프의 this를 가리킨다.
자세한 설명은 다음 게시물을 참고하면 된다.
6. apply, call, bind
JavaScript는 this를 명시적으로 바인딩할 수 있는 apply()
, call()
, bind()
메서드를 제공한다.
call()
매개변수로 this를 바인딩한다.apply()
매개변수로 this를 바인딩한다. 두 번째 매개변수를 배열 형태로 넣어줘야 한다.bind()
매개변수로 this를 바인딩한다. 다만 호출이 발생하지 않는다.
var obj2 = { c: 'd' };
function b() {
console.log(this);
}
b(); // Window
b.bind(obj2).call(); // obj2
b.call(obj2); // obj2
b.apply(obj2); // obj2
참조
'프론트엔드 > JavaScript' 카테고리의 다른 글
[JavaScript] 렌더링 최적화 (Reflow와 Repaint) (0) | 2022.03.24 |
---|---|
[JavaScript] 브라우저 렌더링 (0) | 2022.03.24 |
[JavaScript] Prototype (0) | 2022.01.05 |
[JavaScript] Spread와 Rest의 차이 (0) | 2022.01.02 |
[JavaScript] var, let, const 차이 (0) | 2021.12.14 |