this
는 자신이 속한 객체를 나타내는 자기 참조 변수로,
자바스크립트 엔진에 의해 생성되는데 코드 어디에서나 참조가 가능한 키워드이다
this
의 값은 함수가 호출될 때 호출하는 방식에 따라 달라진다
기본적으로 콘솔에서 this
를 입력해 보면
브라우저 환경의 전역 객체인 Window
를 가리키는 것을 알 수 있다
this
는 항상 전역 객체 (자바스크립트 엔진이 코드를 실행할 때 처음으로 생성되는 컨텍스트)를 참조하기 때문이다!
this
는 함수가 호출될 때 호출하는 방식에 따라 달라진다고 했는데
함수 호출 방식에는 다음과 같은 방식이 있다
함수 선언문에서 일반함수를 호출하는 경우에는 this
는 전역 객체인 Window
를 가리킨다
this
는 자신이 속한 객체를 나타내기 때문에 객체를 생성하지 않는 일반 함수에서는 크게 의미가 없다
어떠한 함수라도 일반함수로 호출되면 Window
를 가리키는 것이다
function func(){
console.log(this);
}
func(); // Window
엄격모드에서는 다른 결과를 볼 수 있다
함수를 직접 호출하여 함수의 컨텍스트가 어디에 속해있는지 알 수 없기 때문에 undefined
를 가리키는 것이다
function func(){
'use strict'; // 엄격모드 지시문
console.log(this);
}
func(); // undefined
📝 엄격모드
- ES5와 함께 등장
- ES5에서 새로운 기능이 추가되고 기존 기능 중 일부가 변경되었는데
기존 기능을 변경하였기 때문에 호환성 문제가 생긴다
때문에 `use strict`라는 특별한 지시문을 통해 엄격 모드를 활성화시키고
활성화시켰을 때만 이 변경사항들을 적용할 수 있도록 해놓았다
+) 엄격모드는 함수 개별적으로 사용하기보다는 script 전체에 적용하는 것을 권장한다
메서드 내부에서 this
키워드를 사용하면 자신이 속한 객체를 참조하는 것을 알 수 있다
메서드를 제대로 사용하기 위해서는 반드시 해당 객체를 명확하게 호출해야 정확한 결과를 얻을 수 있다
const fruit = {
name : 'Apple',
price : 5000,
fruitName : function(){
console.log(this.name);
},
fruitPrice : function(){
console.log(this.price);
},
};
fruit.fruitName(); // Apple
fruit.fruitPrice(); // 5000
이 예시에서는 this
가 fruit
객체의 값을 참조하고 있다
추가 예정
추가예정
화살표 함수 내부에서 this
가 사용된 경우에는 일반함수와 다르게 동작한다
화살표 함수에서 this
는 언제나 상위 스코프의 this
값을 가리킨다
이를 Lexical this 라고 한다
화살표 함수를 감싸고 있는 것이 this
가 참조할 값이라는 얘기이다
// 일반함수
const person = {
name : 'Jan',
greeting : function(){
console.log(`hello ${this.name}!`);
const innerFunc = function(){
console.log(`innerFunc : ${this.name}`);
};
innerFunc();
},
};
person.greeting(); // hello Jan! // innerFunc :
일반함수 innerFunc
에서는 this.name
의 값이 제대로 출력되지 않는다
innerFunc
를 호출하는 시점에 참조하고 있는 객체가 없기 때문이다
↓ 위 코드를 화살표 함수로 수정해 보았다 ↓
// 화살표함수
const person = {
name : 'Jan',
greeting : function(){
console.log(`hello ${this.name}!`);
const arrowFunc = () => {
console.log(`arrowFunc : hello ${this.name}!`);
};
arrowFunc();
},
};
person.greeting(); // hello Jan! // arrowFunc : hello Jan!
화살표 함수 arrowFunc
로 변경 시 this.name
의 값이 상위 스코프의 this.name
값과 같은 것을 알 수 있다
이처럼 화살표 함수를 사용하면 상위 스코프의 this
참조 값을 그대로 상속받게 된다
상위 스코프에서 참조하는 객체는 person
이므로 person의 name인 Jan이 출력되는 것이다
이게 가능한 이유는 화살표 함수에 this
가 없기 때문이라고 한다!
화살표 함수에는 this
라는 변수 자체가 존재하지 않기 때문에 상위 스코프의 this
를 참조하게 된다
화살표 함수에서 this
를 사용할 때 문제가 되는 경우도 있다
const fruit = {
name : 'Apple',
callName : () => console.log(this.name),
callThis : () => console.log(this)
};
fruit.callName(); // undefined
fruit.callThis(); // Window
callName
과 callThis
에 사용된 this
는 호출된 객체 fruit
이 아니라
함수가 선언된 시점의 상위 스코프 전역 객체인 Window
를 가리키게 된다
const Fruit = () => {};
const fruit = new Fruit(); // Uncaught TypeError : Fruit is not a constructor
화살표 함수를 생성자함수로 사용하면 에러가 발생한다
애초에 생성자함수로는 사용할 수 없게 만들어졌다고...!
const button = document.getElementById('Btn');
// 일반함수
button.addEventListener('click', function() {
console.log(this); // button 엘리먼트
});
// 화살표함수
button.addEventListener('click', () => {
console.log(this); // Window
});
addEventListener
의 콜백함수에서는 this
에 해당 이벤트리스너가 호출된 엘리먼트가 바인딩 되도록 정의되어 있다
이처럼 이미 this의 값이 정해져있는 콜백함수에서 화살표 함수를 사용하는 경우,
기존 값이 아니라 상위 스코프의 전역 객체를 참조하기 때문에 Window
를 가리키게 된다
하지만 상위 스코프의 속성들을 쓰기 위해 의도한 것이라면 사용 가능!!!!
면접에서 this가 무엇인지 설명해달라는 질문을 받았을 때 제대로 된 답변을 하지 못했었다
공부하며 정리할겸 이런저런 자료를 많이 찾아봤는데, 공부하면서도 용어나 개념들에 대해 정확히 알고 있지 못해서 애를 먹었다
A 개념을 공부하다 보면 B를 몰라서 찾게 되고, B를 찾아 공부하다 어느 정도 알게 되면 이번에는 C 개념을 몰라서 또 찾게 되고.. 그렇게 끝없이 파보고 있는 중이다
JS 기본기가 중요하다는 것을 뼈저리게 느꼈고 공부에는 정말 끝이 없는 듯하다..😂
사실 이 포스팅도 만족스럽진 못해서 계속 공부하는 대로 추가할 예정!
참고