[JS] this

정재은·2023년 2월 19일
0

JavaScript

목록 보기
10/15
post-thumbnail

1. this란?

this는 자신이 속한 객체를 나타내는 자기 참조 변수로,
자바스크립트 엔진에 의해 생성되는데 코드 어디에서나 참조가 가능한 키워드이다

this의 값은 함수가 호출될 때 호출하는 방식에 따라 달라진다


기본적으로 콘솔에서 this를 입력해 보면

브라우저 환경의 전역 객체인 Window를 가리키는 것을 알 수 있다

this는 항상 전역 객체 (자바스크립트 엔진이 코드를 실행할 때 처음으로 생성되는 컨텍스트)를 참조하기 때문이다!






2. 함수 호출 방식에 따른 this

this는 함수가 호출될 때 호출하는 방식에 따라 달라진다고 했는데
함수 호출 방식에는 다음과 같은 방식이 있다

  • 일반함수
  • 메서드
  • 생성자 함수
  • call( ), apply( ), bind( )

2-1. 일반함수

함수 선언문에서 일반함수를 호출하는 경우에는 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 전체에 적용하는 것을 권장한다

2-2. 메서드

메서드 내부에서 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

이 예시에서는 thisfruit 객체의 값을 참조하고 있다


2-3. 생성자함수

추가 예정

2-4. call( ), apply( ), bind( )

추가예정






3. 화살표 함수에서의 this

화살표 함수 내부에서 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를 참조하게 된다



3-1. 화살표 함수를 사용하면 안 되는 경우

화살표 함수에서 this를 사용할 때 문제가 되는 경우도 있다

[경우1] 메소드

const fruit = {
	name : 'Apple',
  	callName : () => console.log(this.name),
  	callThis : () => console.log(this)
};

fruit.callName();	// undefined
fruit.callThis();	// Window

callNamecallThis에 사용된 this는 호출된 객체 fruit이 아니라
함수가 선언된 시점의 상위 스코프 전역 객체인 Window를 가리키게 된다

[경우2] 생성자함수

const Fruit = () => {};
const fruit = new Fruit();	// Uncaught TypeError : Fruit is not a constructor

화살표 함수를 생성자함수로 사용하면 에러가 발생한다
애초에 생성자함수로는 사용할 수 없게 만들어졌다고...!


[경우3] addEventListener( ) 콜백함수

const button = document.getElementById('Btn');

// 일반함수
button.addEventListener('click', function() {
   console.log(this);	// button 엘리먼트
});

// 화살표함수
button.addEventListener('click', () => {
  console.log(this);	// Window
});

addEventListener의 콜백함수에서는 this에 해당 이벤트리스너가 호출된 엘리먼트가 바인딩 되도록 정의되어 있다

이처럼 이미 this의 값이 정해져있는 콜백함수에서 화살표 함수를 사용하는 경우,
기존 값이 아니라 상위 스코프의 전역 객체를 참조하기 때문에 Window를 가리키게 된다

하지만 상위 스코프의 속성들을 쓰기 위해 의도한 것이라면 사용 가능!!!!






TMI

면접에서 this가 무엇인지 설명해달라는 질문을 받았을 때 제대로 된 답변을 하지 못했었다

공부하며 정리할겸 이런저런 자료를 많이 찾아봤는데, 공부하면서도 용어나 개념들에 대해 정확히 알고 있지 못해서 애를 먹었다

A 개념을 공부하다 보면 B를 몰라서 찾게 되고, B를 찾아 공부하다 어느 정도 알게 되면 이번에는 C 개념을 몰라서 또 찾게 되고.. 그렇게 끝없이 파보고 있는 중이다

JS 기본기가 중요하다는 것을 뼈저리게 느꼈고 공부에는 정말 끝이 없는 듯하다..😂
사실 이 포스팅도 만족스럽진 못해서 계속 공부하는 대로 추가할 예정!



참고

[MDN] this

[생활코딩] this

[코딩알려주는누나] 개발자 면접 단골질문 자바스크립트 this

[MDN] 화살표함수

[모던 자바스크립트 Deep Dive] 화살표함수

[모던 JavaScript 튜토리얼] 엄격모드

profile
프론트엔드

0개의 댓글