JavaScript의 this
by EarlyHail
1. 전역 문맥에서의 this
this의 첫 번째 동작 방식은 전역 객체를 참조하는 것이다.
-
Node 환경에서는
global
객체 -
브라우저 환경에서는
window
객체console.log(this === window); // ture var hoisting = 1; console.log(this.hoisting); // 1 console.log(window.hoisting); // 1 window.a = 5; console.log(this.a); // 5 this.b = 10; console.log(window.b); // 10
2. 함수 문맥에서의 this
함수 내부에서 this
는 호출 방식에 의해 결정된다.
1) 단순 호출
-
단순히 함수를 호출할 경우
this
의 값이 결정되지 않는다. 따라서this
는 전역객체를 참조한다.function f1() { return this; } const f2 = () => { return this; }; console.log(f1() === window); // true console.log(f2() === window); // true
2) bind 함수 사용 (명시적 바인딩)
-
Function.prototype.bind
를 사용하여 bind할 경우 this는 bind()의 첫 번째 매개변수이다.function func() { return this; } const bindFunc = func.bind({ name: "Early Hail" }); console.log(bindFunc()); // { name: "Early Hail" }
3) 화살표 함수
-
화살표 함수에서 this는 선언된 부분의 this context를 사용한다.
암시적 바인딩이 발생하지 않는다.
const obj = { arrowFunc: () => this, func: function () { return this; }, }; console.log(obj.arrowFunc() === window); // true console.log(obj.func() === window); // false
코드 상으로 arrowFunc가 선언된 부분은
obj
라고 생각할 수 있지만 obj객체가 만들어 질 때의 this는 window 객체이므로 선언된 부분의 this는window
이다. (this가 obj로 바인딩되지 않음) -
화살표 함수에서 this는 bind()에 의해 변경되지 않는다. (call, apply 포함)
const func = () => { return this; }; const bindFunc = func.bind({ name: "Early Hail" }); console.log(bindFunc() === window);
4) 객체의 메소드
함수가 객체의 메소드로 호출될 때 해당 함수의 this는 객체를 가르킨다. (암시적 바인딩)
var a = 10;
const obj = {
a: 100,
arrowFunc: () => this.a,
func: function () {
return this.a;
},
};
console.log(obj.arrowFunc()); // 10, this는 window
console.log(obj.func()); // 100, this는 obj
Arrow Function의 경우 암시적 바인딩이 발생하지 않으므로 this는 window이다.
var a = 10;
const obj = {
a: 100,
func: function () {
return this.a;
},
};
const globalFunc = obj.func;
console.log(globalFunc()); // 10, this는 window
obj.arrowFunc
는 객체의 메소드이다.
하지만 obj
를 통해 호출된것이 아닌 전역 객체에서 func
를 호출한 것이므로 this는 window이다.
생성자로서의 this
함수를 new 키워드와 함께 생성자로 사용하면 this는 새로 생긴 객체에 바인딩된다.
class문법에서의 this도 해당 객체에 바인딩된다.