일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
Tags
- 인터섹션
- recoil
- app router
- 이분 검색
- Promise
- 호이스팅
- 리터럴 타입
- CI/CD
- 무한 스크롤
- Cypress
- RTK Query
- ESlint
- dfs
- 결정 알고리즘
- webpack
- React
- 반공변성
- useAppDispatch
- TS
- SSR
- autosize
- 공변성
- tailwind
- map
- 타입 좁히기
- 투포인터
- CORS
- 태그된 유니온
- Jest
- async/await
Archives
- Today
- Total
짧은코딩
this(this는 호출 시 결정) 본문
반응형
JS의 this는 다른 언어와 좀 다르다.
console.log(this)를 하면 window가 나온다.
기본적으로 this는 window라고 생각하면된다.
-함수
function a() {
console.log(this);
}
a();
함수에서도 this는 window가 나온다.
globalThis
JS에서는 window, Node에서는 global
=> 최근 스팩에서는 globalThis로 합쳐짐
window의 2가지 역할
- 브라우저 안의 모든 요소들이 소속된 객체로, 최상위에 있기에 어디서든 접근이 가능해서 '전역 객체'라고도 부른다.
- 일반적으로 우리가 열고 있는 브라우저의 창을 의미하고, 이 창을 제어하는 다양한 메서드를 제공한다.
- ex) window.innerWidth, window.innerHeight 등
'use strict' 모드
function a() {
'use strict'
console.log(this);
}
a();
strict 모드에서는 this가 undefined가 나와야 한다.
this가 변하는 경우
-예시1
const obj = {
name: 'zerocho',
sayName() {
console.log(this.name);
}
};
obj.sayName();
여기서 this는 obj
-예시2
const obj = {
name: 'zerocho',
sayName() {
console.log(this.name);
}
};
const sayN = obj.sayName;
sayN();
여기서 this는 window
-예시3(화살표 함수)
const obj = {
name: 'zerocho',
sayName: () => {
console.log(this.name);
}
};
obj.sayName();
여기서 this는 window
화살표 함수인지 아닌지도 this를 결정하는데 큰 역할을 함
-예시4(new)
-예시5
- bind는 새로운 함수를 만드는 것
- apply, call은 새로운 함수를 만들고 호출까지 해주는 것
- a.apply(window) === a.bind(window)() === a.call(window)
-apply, call의 차이점
function add(a, b) { return a+b }
add.apply(null, [3,5]);
add.call(null, 3, 5);
- add에서 this를 사용하지 않기에 apply, call 둘 다 this 자리에 null을 넣어도 됨
- apply는 인자를 배열로 넣고
- call은 인자를 그냥 값으로 넣음
✅여기서 중요한 점
const obj = {
name: 'zerocho',
sayName() {
console.log(this.name); // 이 부분 this
}
};
위 코드의 this는 항상 obj인게 아니다
-this 결정 규칙
- 가장 기본적으로 this는 window
- 바뀌는 경우
- obj.sayName()처럼 함수 앞에 객체가 붙으면 this가 앞의 객체(obj)가 됨
- new를 사용하는 경우
- bind, apply, call로 this를 바꿔주는 경우
- 화살표 함수에서는 부모의 this를 물려받음(이때 부모가 어떻게 호출되었는지에 따라 또 달라짐)
어떻게 판단할까?
=> 렉시컬 스코프처럼 코드 작성 시 정해지는 것이 아니라, this는 함수가 호출될 때 정해진다.
문제
(1) console.log의 결과는?
const obj = {
name: 'zerocho',
sayName () {
console.log(this.name);
function inner() {
console.log(this.name);
}
inner();
}
};
obj.sayName();
더보기
결국 inner() 안의 console.log의 this는 window이다.
-이유
- obj.sayName()에서는 obj가 앞에 붙었고, sayName이 화살표 함수가 아니기 때문에 'zerocho'가 출력
- inner()는 함수 호출 시, this를 바꾸는 행동을 아무것도 안해서 window가 됐다.
=> 결국 this는 호출 시 결정된다!!
(2) console.log의 결과는?
const obj = {
name: 'zerocho',
sayName () {
console.log(this.name);
const inner = () => {
console.log(this.name);
}
inner();
}
};
obj.sayName();
더보기
둘 다 sayName이 된다.
-이유
- inner() 안의 this가 바뀐 것을 보려면, 우선 함수가 호출될 때를 보면된다.
- 일단 inner();에서는 this를 바꿔주는 행동을 안했다.
- 화살표 함수는 부모 함수의 this를 가져온다.
- 여기서 inner()의 console.log의 this는 obj.sayName()이 실행됨으로써 실행되었다.
- 따라서 sayName의 this가 적용된다.
그렇기에 이 부분만 보고 this를 물어보면, this는 모른다고 답해야 한다.
this는 호출 시에 결정되기 때문이다!
(3) console.log의 결과는?
const obj = {
name: 'zerocho',
sayName () {
console.log(this.name);
const inner = () => {
console.log(this.name);
}
inner();
}
};
const sayN = obj.sayName;
sayN();
더보기
둘 다 this는 window가 된다.
-이유
- sayN에 담았다가 꺼낼 때 this를 바꿔주는 행동을 하지 않았기 때문이다.
- 결국 그냥 함수로 호출하면 무조건 this는 window다.
분석
호출 스택 분석1(strict 모드가 아닐 때)
- 처음엔 anonymous가 호출 스택에 쌓이고, this = window
- obj.sayName이 호출 스택에 쌓이고, obj 객체가 앞에 있기에 this = obj
- console.log를 하여 첫번째 'zerocho' 출력
- inner가 호출 스택에 쌓이고, 화살표 함수라 부모의 this를 받아서 this = obj
- console.log를 하여 두번째 'zerocho' 출력
호출 스택 분석2(strict 모드가 아닐 때)
- 처음엔 anonymous가 호출 스택에 쌓이고, this = window
- obj.sayName이 호출 스택에 쌓이고, obj 객체가 앞에 있기에 this = obj
- console.log를 하여 첫번째 'zerocho' 출력
- inner가 호출 스택에 쌓이고, inner()는 그냥 함수고 화살표 함수도 아니라 this = window
- console.log를 하여 window의 name ''출력
-출처
https://www.youtube.com/watch?v=pgo6URFz8tc&list=PLcqDmjxt30Rt9wmSlw1u6sBYr-aZmpNB3&index=7
반응형
'JS > 인간 JS엔진' 카테고리의 다른 글
블록 스코프와 매개변수 (0) | 2024.01.24 |
---|---|
this를 분석할 수 없는 케이스 (0) | 2024.01.23 |
호이스팅 (0) | 2024.01.21 |
스코프 체인 (0) | 2024.01.21 |
호출 스택 분석 (0) | 2024.01.20 |
Comments