1. 기본 window를 의미함
console.log(this);
과거 this를 출력하면 js에서는 window 전역 객체가 호출되고, node에서는 global 전역 객체가 호출되었다.
하지만 이렇게 쓰일 경우 js와 node에 따라 분기처리를 해줘야하는 불편함이 있었다.
그래서 최근에는 globalThis로 통합이 되었다.
2. strict 모드
function a(){
'use strict'
console.log(this);
}
a();
기존 this를 쓰면 globalThis가 도출된다고 했지만
'use strict'를 함께 써주면 this는 undefined가 된다.
3. this가 변경될 때
this가 변경되는 3가지 경우가 있다.
1) 객체 안에 있을 때
const obj = {
name: 'zerocho',
sayName(){
console.log(this.name);
}
};
obj.sayName(); //zerocho
객체 안의 this를 호출할 때는 window가 아닌 obj 객체이기 때문이다.
하지만 this는 항상 obj로 치환되지 않는다. 예를 들어 아래와 같은 경우이다.
const obj = {
name: 'zerocho',
sayName(){
console.log(this.name);
}
};
const sayN = obj.sayName();
console.log(sayN); //''
obj의 함수를 다른 변수에 넣어주고 출력하면 this는 obj가 아니다.
2) 생성자 함수 안에 있을 때
function Human(name){
this.name = name;
}
new Human('zerocho'); // Human{name:'zerocho'}
new로 생성자 함수를 생성하는 경우 this가 바뀐다.
3) this를 강제로 바꿔줄 때
function sayName(){
console.log(this.name);
}
sayName();
이 경우 this는 window이다. strict 모드가 아니기 때문이다.
this를 바꿔주는 방법은 bind, call, apply 3가지가 있다.
- bind
sayName.bind({name: 'zerocho'})();
this를 안에 {} 객체로 치환한다.
bind는 새로운 함수를 만드는 친구이기 때문에 ()로 호출을 따로 해줘야 한다.
이런 이유로 sayName.bind({name : 'zerocho'})() 이렇게 실행해주면, zerocho가 도출된다.
- apply & call
sayName.apply({name: 'zerocho'})
sayName.call({name: 'zerocho'})
bind와 유사한 기능을 하는 apply와 call은 차이점이 있다면, 새로운 함수를 만들어주고, 호출까지 해준다는 것이다.
그러면 대체 this는 어떻게 봐야 하는건가?
this는 함수가 호출될 때 정해진다.
4. 화살표 함수에서 this
const obj = {
name: 'zerocho',
sayName: () =>{
console.log(this.name);
}
};
obj.sayName(); //'' == window.name
화살표 함수는 this를 결정짓는 중요한 요소이다.
화살표 함수에서는 부모의 스코프를 물려받는다. (스코프는 선언이다.)
때문에 스코프 체인을 잘 파악해야 한다. 스코프 체인은 현재 함수에서 다른 값에 접근을 할 수 있나 없나를 확인하기 위한 것이다.
const obj = {
name:'zerocho',
sayName(){ //화살표 함수 sayName: () =>
console.log(this.name);
function inner(){
console.log(this.name);
}
inner(); //inner.call(obj) 조작 가능
}
}
예를 들어 위 코드의 스코프 체인은 inner -> sayName -> anonymous이다.
화살표 함수도 선언이기 때문에 화살표 함수로 스코프 체인을 표현해도 위와 같다.
위 코드를 obj.sayName()으로 실행하면 결과는 zerocho, ''으로 나온다.
왜냐하면 sayName()을 호출할 때 obj를 앞에 붙여서 호출을 했고, 또한 화살표 함수도 아니기 때문에 this가 obj가 된 것이다.
inner()라고 함수를 호출할 때는 앞에 아무것도 붙여주지 않았고, call, bind, apply로 변경도 안해줬다. 그래서 inner의 this.name = window.name = ''이다.
const obj = {
name:'zerocho',
sayName(){
console.log(this.name);
const inner = () => {
console.log(this.name);
}
inner();
}
}
근데 만약 inner함수가 화살표 함수라면 이야기는 달라진다.
화살표 함수는 부모 함수의 this를 가져온다.
부모의 this함수는 호출될 때 obj를 붙여 호출되어 this가 obj이고, 따라서 inner 함수의 this도 obj이다.
따라서 결과는 zerocho, zerocho가 나온다.
다시 한 번 강조하면 코드만 보고 this를 판단할 수 없다. 모른다.
호출될 때 this를 판단할 수 있다.
'프로그래밍 언어 > Javascript' 카테고리의 다른 글
비동기는 동시가 아니다. 순서의 문제다. (1) | 2024.01.25 |
---|---|
Promise (3) | 2024.01.24 |
함수와 함수의 호출, 고차함수 (0) | 2024.01.23 |
드림코딩 엘리와 함께하는 자바스크립트 기초 다지기 : 번외. 반응형 헤더 만들기 위해 필요한 요소들, 프로젝트 할 때 필수 사이트 모음 (0) | 2021.11.08 |
드림코딩 엘리와 함께하는 자바스크립트 기초 다지기 : 4. 반복문, operator (0) | 2021.11.07 |