이 영역을 누르면 첫 페이지로 이동
Nuhends 의 Tech Life 블로그의 첫 페이지로 이동

Nuhends 의 Tech Life

페이지 맨 위로 올라가기

Nuhends 의 Tech Life

IT / Tech / 재테크 관련 뉴스를 최대한 알기 쉽게 전달하는 Tech 블로그 입니다.

[JS] this란? 모든 케이스를 정리해보자

  • 2021.06.08 16:37
  • 프로그래밍/JAVASCRIPT 사전
반응형

 

 

 

 

[JS] this란? 모든 케이스를 정리해보자

자바스크립트에서 this란?

 

 

⚡️ this란?

 

 

'그'는 나에게로 와서 꽃이 되었다.

 

 

위 문장에서 '그' 는 누굴까? 상황에 따라 바뀔 것이다. 옆집 아저씨가 될 수도 있고, 할아버지가 될 수도 있고, 편의점 알바생이 될 수도 있다. 그를 파악하기 위해서는 전, 후 문장에서 단서가 필요하다. 그 단서를 통해 문맥 상황에서 '그'가 누군지 추론할 수 있다.

 

- 자바스크립트 세계관에서도 '그' 와 같은 개념이 this 라는 예약어이다.

- this는 자바스크립트 엔진에 의해 암묵적으로 생성되기 때문에, 상황에 따라 가리키는 대상이 바뀔 수 있다.

즉, this는 문맥에 따라 그 의미(값)가 변경된다.

 

 

👨🏻‍💻 예시 코드

const name = 'something box';

function getBoxName() {
	console.log(this.name);
}

const obj = {
	name: 'moon',
  	box: getBoxName,
};

getBoxName(); // ?
obj.box();    // ?

 

line 12, 13 는 둘 다 getBoxName 이라는 동일한 함수를 실행시킨다. 하지만 그 결과는 다르게 찍힌다.

 

- line 12: getBoxName 이라는 일반 함수를 실행하였다. 이런 경우 this는 전역 객체(=window)를 가리킨다.

- line 13: obj.box는 getBoxName을 참조하여, getBoxName를 실행시킨다. 하지만 obj.box의 형식으로 dot notation방식으로 실행시킬 경우 obj가 this로 바인딩된다.

 

즉, point는 "함수를 어디서 어떻게 실행하는가" 이다

→ 해당 함수를 실행시키는 부분을 찾아서 파악해야 한다.

(this를 이용하는) 함수를 실행하는 방법은 크게 4가지 경우로 나눌 수 있다. 해당 함수가 어떤 방식으로 실행되느냐에 따라 this의 값이 바뀐다. 

 

 

 

⚡️ 함수를 실행하는 4가지 방식

 

👉 1. 일반 함수 실행 방식

 

함수가 일반적인 방식으로 실행되면 전역 객체(=window)

function foo() {
	console.log(this); // ?
}

foo();  // ?

 

- line2: 선언된 부분만 보고는 this가 무엇인지 절대 알 수 없다.

- line5: 일반 함수 방식으로 실행되었으므로, this는 전역 객체(=window)를 가리킨다.

 

 

'use strict' 모드일 경우 this는 undefined

'use strict'

const name = 'ken';

function foo() {
	console.log(this.name);   // ?
}

foo();  // ?

- line1: use strict 모드 명시

- line6: use strict 모드이기 때문에 함수가 어떻게 실행되었는지 상관없이 this는 undefined

- line9: this는 undefined이고, undefined.name이 되면서, Uncaught TypeError 발생

 

 

+ 추가: strict mode를 사용하는 이유

어떤 사람이 함수를 실행할 때 window를 참조하기 위해 this 키워드를 사용하여 코드를 작성하였다. 하지만 다른 동료가 해당 함수를 메서드로 사용할 경우, dot Notation으로 접근 시 this는 다른 객체를 참조하게 되면서 의도하지 않은 결과를 발생시키게 된다. 이는 버그라고 볼 수 있다. 이런 경우 명시적으로 strict mode를 사용하여 this를 undefined로 만들어 이후 발생할 수 있는 예기치 못한 에러를 잡아주는 역할을 한다.

 

 

❗️QUIZ

var height = 180;

function bar() {
	console.log(this.height);
}

function foo() {
	var height = 150;
	bar();
}

foo();

- strict mode가 아니다

- line4: bar 함수는 this 키워드 사용

- line9: 일반 함수 실행 방식으로 bar함수가 호출 → this는 window를 가리키고, window.height인 180을 출력

 

 

 

👉 2. Dot Notation

 

Dot Notaion 방식으로 실행 시 this는 해당 객체를 참조

 

❗️QUIZ

var height = 150;
var person = {
	height: 180,
	foo: function foo() {
		console.log(this.height);
	}
};

person.foo();

- line9: foo 함수는 person 객체의 dot notation 방식으로 실행 → this는 person 객체

- this가 person로 바인딩되기 때문에, window.height가 아닌 person.height를 참조

 

❗️QUIZ

function foo() {
	console.log(this.height);
}

var height = 50;
var tony = {
	height: 170,
	foo: foo
};
var elon = {
	height: 200,
	foo: function () {
		console.log(this.height);
	}
};

tony.foo();  // ?
elon.foo();  // ?

- line 17, 18: 둘 다 dot notation 방식으로 함수를 실행, foo 함수의 this는 각각 tony, elon을 바인딩

 

 

❗️QUIZ

var height = 100;
var tony = {
	height: 170,
	foo: function bar() {
		console.log(this.height);
	}
};
var elon = {
	height: 200,
	foo: tony.foo
};

var foo = tony.foo;

tony.foo();  // Q1
elon.foo();  // Q2
foo();      // Q3

- line 15, 16: 이전 퀴즈와 동일하게 this는 각각 tony, elon에 바인딩

- line 17: foo는 일반 함수 실행 방식, this는 window에 바인딩되므로 100이 출력

 

 

❗️QUIZ

 

 

 

👉 3. call, bind, apply

Function.prototype.call : 첫 번째 인자로 전달한 객체를 this에 바인딩하고, 함수를 실행
Function.prototype.apply : 첫번째 인자로 전달한 객체를 this에 바인딩하고, 함수를 실행
Function.prototype.bind : 첫번째 인자로 전달한 객체를 this에 바인딩하고, 해당 함수를 반환

⇒ 함수 객체라면 프로토타입 체이닝을 통해 call, apply, bind 메서드를 사용할 수 있다.

 

var age = 100;

function foo() {
	console.log(this.age);
}

var elon = {
	age: 35
}
var tony = {
	age: 31
}

foo();         // Q1 : window
foo.call(elon); // Q2 : ?
foo.apply(tony) // Q3 : ?

- Q1 :

    - foo 함수가 일반 함수 실행, this는 window 객체

- Q2:  

    - foo.call 함수가 실행 인자로는 elon 객체가 전달

    - 인자로 전달된 elon 객체가 foo함수의 this로 바인딩

- Q3 

    - foo.apply 함수가 실행 인자로는 elon 객체가 전달

    - 인자로 전달된 tony 객체가 foo함수의 this로 바인딩

 

foo라는 함수를 실행할 건데 call 혹은 apply를 통해
this로 바인딩할 객체를 첫 번째 인자로 명시적 전달할 수 있다.

 

call과 apply의 차이

var age = 100;

function foo(a, b, c, d, e) {
	console.log(this.age);
	console.log(arguments);
}

var tony = {
	age: 35
};

foo.call(tony);
foo.apply(tony, [1, 2, 3, 4, 5]);

call과 apply의 차이는 

foo 함수에서 사용할 두 번째 인자들(a, b, c, d, e)를 전달하는 방식에 있다. (1번 인자는 동일)

 

- call

    - 1번 인자: this로 바인딩할 객체

    - 2~n번 인자: 함수에서 arguments로 사용할 인자를 차례대로 전달

- apply

    - 1번 인자: this로 바인딩 할 객체

    - 2: 함수에서 arguments로 사용할 인자를 배열 형태로 전달

 

 

❗️QUIZ

var age = 100;

function foo() {
	console.log(this.age);
}

var tony = {
	age: 35
}

var bar = foo.bind(tony);

bar(); // ?

- bar() 라는건, bar는 함수를 의미 ⇒ foo.bind는 함수를 리턴

- foo.bind 함수의 인자로는 foo 함수에서 this로 바인딩할 객체를 전달하여 this를 명시적 바인딩

 

❗️QUIZ

var age = 100;

function foo() {
	console.log(this.age);
	console.log(arguments);
}

var elon = {
	age: 34
}

var bar = foo.bind(elon);

bar(1, 2, 3, 4, 5); // ?

- foo.bind(elon): elon 객체를 this에 바인딩하고 해당 함수를 return

- bar(1, 2, 3, 4, 5) : 함수에 1, 2, 3, 4, 5 인자가 전달

 

 

👉 4. new 키워드

 

new 키워드로 함수를 호출할 경우 특정 과정으로 동작한다.

function foo(name, age) {
	console.log(this);
	return this;
}

console.log(foo());    // Q1
console.log(new foo());    // Q2

- Q1. 일반 함수 호출 방식이므로 this는 window 객체

- Q2. new 키워드로 함수를 호출한 경우 아래 코드와 같은 내부 동작이 진행된다.

 

new 키워드의 내부 동작

function foo(name, age) {
	this = {};
	console.log(this);
	this.name = name
	this.age = age

	this.__proto__ = foo.prototype

	return this;
}

1. 새로운 빈객체 {} 를 생성하고 this는 이 객체를 참조한다.

2. 1에서 만든 빈 객체(this)에 foo함수에서 인자로 받은 name, age를 property로 할당

3. 빈 객체(this)에 __proto__ 프로퍼티가 foo.prototype를 가리키도록 한다. (프로토타입 체이닝을 위해)

4. 최종적으로 this(생성한 객체)를 리턴

 

즉 new 키워드로 함수 호출 시 this는 생성된 객체를 가리키고, 해당 함수를 생성자 함수라고 한다.
이는 프로토타입, 프로토타입 체이닝 개념에 대한 이해가 필요한데, 자세한 내용은 아래 포스팅 참고

 

 

👉 + 화살표 함수(arrow function)

 

화살표 함수의 this는 일반 함수와 달리 상위 스코프의 this를 가리킨다.

let group = {
  title: "1모둠",
  students: ["보라", "호진", "지민"],
  showList() {
    this.students.forEach(function(student) {
      alert(this.title + ': ' + student)
    });
  }
};

group.showList();

- line5: showList 함수는 dot notation 방식으로 실행, this는 group 객체

- line7: forEach에 인자로 전달된 함수는 일반 함수이므로 this는 window 객체

- 예상과 다르게 "undefined: 보라", "undefined: 호진", "undefined: 지민" 을 출력

 

let group = {
	title: "1모둠",
	students: ["보라", "호진", "지민"],
	showList() {
		this.students.forEach(student => alert(this.title + ': ' + student));
	}
};

group.showList();

- forEach에 인자로 화살표 함수가 전달 

- this.title은 화살표 함수 바깥에 있는 showList 메서드에서 this가 가리키는 대상(group 객체)과 동일해진다.

 

 

 

 

 

 

참고

- https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this

- https://poiemaweb.com/js-this

- https://poiemaweb.com/es6-arrow-function

 

 

반응형
저작자표시 비영리 변경금지 (새창열림)

'프로그래밍 > JAVASCRIPT 사전' 카테고리의 다른 글

[JS] 모듈 import/export 문법 빠르게 정리하기  (0) 2021.09.18
[JS] scope 와 실행 컨텍스트  (0) 2021.06.11
[JS] 화살표 함수, 쉽고 빠르게 정리하기  (8) 2021.05.11
[YOU DON'T KNOW JS 정리] THIS (1)  (4) 2021.05.08
[JS] arguments 객체 그리고 유사배열 객체  (0) 2021.05.05

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • [JS] 모듈 import/export 문법 빠르게 정리하기

    [JS] 모듈 import/export 문법 빠르게 정리하기

    2021.09.18
  • [JS] scope 와 실행 컨텍스트

    [JS] scope 와 실행 컨텍스트

    2021.06.11
  • [JS] 화살표 함수, 쉽고 빠르게 정리하기

    [JS] 화살표 함수, 쉽고 빠르게 정리하기

    2021.05.11
  • [YOU DON'T KNOW JS 정리] THIS (1)

    [YOU DON'T KNOW JS 정리] THIS (1)

    2021.05.08
다른 글 더 둘러보기

정보

Nuhends 의 Tech Life 블로그의 첫 페이지로 이동

Nuhends 의 Tech Life

  • Nuhends 의 Tech Life의 첫 페이지로 이동
반응형

검색

메뉴

  • 홈
  • 웹 개발
  • 경제 데이터
  • 경제 공부
  • 방명록

카테고리

  • 분류 전체보기 (127)
    • 프로그래밍 (69)
      • React (3)
      • HTML&CSS 사전 (13)
      • JAVASCRIPT 사전 (11)
      • Algorithm (23)
      • 이슈 정리 (2)
      • 개발 환경 (4)
      • NodeJS (1)
      • Typescript (4)
      • NextJS (5)
      • React-Query (2)
      • ai (1)
    • 경제 데이터 (22)
      • 주식 순위 (20)
      • 경제지표 (2)
    • 경제 공부 (25)
      • 경제 신문 읽기 (3)
      • 세금 재테크 (7)
      • 인사이트 (4)
      • 경제용어정리 (9)
      • 정부 지원 제도 관련 (2)
    • 팁 모음 (11)
      • 인터넷 (5)
      • 생활 (3)
      • SNS 맛집 (3)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • 코테 풀이
  • softeer
  • 코테
  • 코딩테스트
  • javascript
  • 프로그래머스
  • 자바스크립트
  • 알고리즘

나의 외부 링크

정보

nuhends의 Nuhends 의 Tech Life

Nuhends 의 Tech Life

nuhends

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © nuhends. Designed by Fraccino.

티스토리툴바