치춘짱베리굿나이스
this in JavaScript 본문
this
매우 매우 헷갈리는 그 this
이다
전역 스코프에서의 this
브라우저
console.log(this);
브라우저에서의 전역 스코프에서 this
는 Window
객체를 가리킨다
Node.js
node.js 환경에서의 this
는 현재 module.exports
객체를 가리킨다고 한다
브라우저처럼 Global
객체를 가리킬 것 같지만 아니다
const a = 2; // 영향 X
module.exports.a = 3;
console.log(this);
따라서 해당 객체에 값을 넣으려면 module.exports
를 해 주어야 한다
console.log(globalThis);
globalThis
가 global
객체를 가리킨다
함수 호출 시의 this
단순 호출
function foo() {
console.log(this);
}
foo()
단순 호출 시에는 호출된 시점에서의 부모 객체를 참조하므로, 위에서 foo
가 호출되었을 때의 부모 객체인 Window
(또는 global
) 객체가 출력된다
객체 내부에서의 호출
function foo() {
console.log(this);
}
const class1 = {
value: 1,
func: foo,
};
class1.func();
객체 내부에서 객체의 메서드로서 호출이 될 경우 해당 객체가 출력된다
객체 내부에 있는 함수를 외부로 빼내어 호출
function foo() {
console.log(this);
}
const class1 = {
value: 1,
func: foo,
};
const func = class1.func;
func();
이 경우 함수 func
는 전역에서 호출되었으므로 전역 객체가 출력된다
생성자
function foo() {
this.value = 2;
}
const obj = new foo();
console.log(obj.value);
함수를 생성자로 사용할 경우, this
는 새로 생성되는 객체를 가리킨다
call, apply, bind
call
function foo() {
console.log(this);
}
const class1 = {
value: 1,
func: foo,
};
const class2 = {
value: 2,
};
class1.func.call(class2);
call
을 이용하면 this
를 재할당한 뒤 함수를 호출할 수 있다
여기서 func
의 this
를 class2
로 바꿔준 뒤 호출했으므로 value
는 2가 된다
function foo(n) {
console.log(this);
console.log(n);
}
const class1 = {
value: 1,
func: foo,
};
const class2 = {
value: 2,
};
class1.func.call(class2, 2);
call
은 두 번째 인자부터 “실행시킬 함수의 인자”를 받는다
여기서 두 번째 인자에 2
를 넘겼기 때문에 foo(n)
의 n
에 2
가 들어갔음을 확인할 수 있다
apply
function foo() {
console.log(this);
}
const class1 = {
value: 1,
func: foo,
};
const class2 = {
value: 2,
};
class1.func.apply(class2);
call
메서드와 완전히 동일한 동작을 한다
부모 객체가 바뀌어 class2
가 출력되는 것을 볼 수 있다
function foo(n) {
console.log(this);
console.log(n);
}
const class1 = {
value: 1,
func: foo,
};
const class2 = {
value: 2,
};
class1.func.apply(class2, [2]);
apply
는 call
과 다르게 “실행시킬 함수의 인자” 를 배열로 받는다는 차이가 있다
bind
function foo() {
console.log(this);
}
const class1 = {
value: 1,
func: foo,
};
const class2 = {
value: 2,
};
const bar = class1.func.bind(class2);
bar();
bind
는 부모 객체 (this
) 를 영구적으로 바꾼 값을 반환한다
bar
함수는 func
의 부모 (this
) 를 class2
로 바꾸어준 결과물이다
화살표 함수
호출
const func = () => {
console.log(this);
};
const class1 = {
value: 1,
func: () => {
console.log(this);
},
};
func();
class1.func();
화살표 함수는 this
가 없기 때문에 상위 스코프에서 this
를 찾는다
따라서 위의 경우에는 전역 스코프를 가리키게 된다
const class1 = {
value: 2,
func: function () {
const foo = () => {
console.log(this);
};
foo();
},
};
class1.func();
이렇게 하면 func
함수의 스코프에서 this
가 존재하므로, 해당 this
를 가져와 출력한다
bind, call, apply
const class1 = {
value: 1,
func: () => {
console.log(this);
},
};
const class2 = {
value: 2,
};
class1.func.call(class2);
class1.func.apply(class2);
const bar = class1.func.bind(class2);
bar();
화살표 함수는 bind
, call
, apply
를 무시한다는 것을 기억하자
화살표 함수의 this
는 함수 생성 시점의 것으로 고정된다
참고 자료
https://www.reddit.com/r/node/comments/cjbn9x/why_this_is_empty_in_global_scope_in_nodejs/
https://stackoverflow.com/questions/43627622/what-is-the-global-object-in-nodejs
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this
'Javascript + Typescript > 이론과 문법' 카테고리의 다른 글
문자열의 특정 문자 변경하기 (0) | 2023.08.08 |
---|---|
2차원 배열에서 값 단 하나만 바꾸고 싶은데 모든 줄이 다 바뀌는 경우 (0) | 2023.08.08 |
클로저 (2) | 2023.07.18 |
UnhandledPromiseRejection (0) | 2023.07.17 |
[Typescript] 인덱스 시그니쳐 (0) | 2023.07.14 |