globalThis.name = 'Global Name';
const obj = {
name: 'Obj Name',
printName() {
console.log(this.name);
},
};
const printName = obj.printName;
// obj = null;
printName();
// 정답: 'Global Name'이 출력된다
this!!
우선적으로 알아야 할것은 this는 렉시컬 스코프처럼 동작하지 않는다!!!
this는 렉시컬 스코프와 다르게 함수가 어디서 호출되었는지에 따라 결정된다.
함수 호출방식에 따른 this
| 실행되는 함수의 종류 | 브라우저 | node |
| 함수 선언문 function(){} |
FunctionDeclaration에 <f.o>로 등록 bind 한 객체 bind하지 않았다면 전역([[globalThisValue]]) |
좌동 |
| 화살표 함수 () => {} |
bind 안 됨! 전역(globalThisValue) 소유자의 Lexical Scope의 this |
bind 안 됨! 모듈 |
| 객체/instance method | 객체 또는 instance 자신 | 좌동 |
| method 내 inner function 선언문 | window (globalThis) | global (globalThis) |
| 함수 선언문 Property (f: function()) |
FunctionDeclaration에 <f.o>로 등록 소속된 객체 (method) |
좌동 |
| 화살표 함수 Property 화살표 callback 함수 |
소속된 객체의 부모(소유자) | 좌동 |
일반(함수 선언문)함수는 <f.o>로 등록되어 FunctionDeclaration(함수테이블)의 주소를 참조!
즉, 실행되는 위치에 따라 thisValue의 binding이 달라 진다!
위 표를 따르면 함수선언문 형태의 함수에서 따로 this가 bind 되지 않았다면 this는 전역([[globalThisValue]]) 이라는 거다.
근데 예제에서는 obj.printName을 담았는데 왜? this가 전역객체인가? 객체안에 존재하므로 this에 객체 obj가 바인딩되지 않나???
const printName = obj.printName;
이 코드에서 printName에는 함수객체만 따로 담긴다.
호출대상인 obj는 더이상 남아있지 않는다. => obj에서 메서드를 떼어냈다.
결국 함수선언문 형태인 printName 함수가 전역 실행 컨텍스트에서 정의 되었고 전역 객체의 컨텍스트에서 해당 함수가 호출되었으므로 this는 globalThis (브라우저에선 window) 가 바인딩된다라고 보면된다.
예를들어 코드가
obj.printName(); // "Obj Name" 출력
이렇게 호출되었다면??
이경우는 메서드 호출이므로 this가 obj로 바인딩된다.
this 참 어렵다.....🥹
'Dev > Javascript' 카테고리의 다른 글
| [JS] 비동기 프로그래밍 (1) | 2025.05.20 |
|---|---|
| [JS] 배열 (Array) (1) | 2025.04.15 |
| [JS] 객체와 프로퍼티 (0) | 2025.04.10 |
| [JS] 피보나치 수열 구현하기 (0) | 2025.04.10 |
| [JS] 클로저 (Closure) (0) | 2025.04.09 |
