# 함수와 클래스에서 this

## 1. 함수에서 this

함수에서 this는 함수를 실행시키는 주체를 말한다.  아래 예시를 보자.&#x20;

this가 출력되는 show 함수를 정의한다. 그리고 fn 객체의 아이템으로 show 함수를 참조하게 한다.&#x20;

```javascript
function show() {
    console.log(this)
}

var fn = {
    show
}
```

fn 객체의 show 함수에 접근해보자 fn.show 구문으로 접근하면 결과는  show는 show() 함수를 참조하고 있다고 알려 준다.&#x20;

```javascript
fn.show

// 출력되는 결과 
ƒ show() {
    console.log(this)
}
```

그러면 이번엔 함수를 실행 시켜보자. 아래 출력된 결과는 `this`이다. 즉, 현재 show() 함수를 실행시킨 주체가 fn 객체가 출력된다. &#x20;

```javascript
fn.show()

// {show: ƒ}
```

![{show: f}는 fn 객체를 말한다. ](https://831271375-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSRg9KgNRIGErVFy_6g%2F-MT_3_25Bp852pL4w_F1%2F-MT_43dtDe3Ub4e3kLPF%2Fimage.png?alt=media\&token=b7ba6dfb-ae4a-465d-b5b1-1ec22369182d)

{% hint style="info" %}
아래의 구문이 사실 이해가 잘 안됐다. 그래서 fn.show == fn.show()가 성립되는 줄 알았다. 하지만 절대 아니다. fn.show == show 와 같은 것이다.&#x20;

```javascript
{show: ƒ}
```

하지만 위의 구문을 보기 쉽게 적어보면 아래와 같다.&#x20;

```javascript
var fn = {
    show: function() {
        console.log(this)
    }
}

console.log(fn) // {show: ƒ}
```

이번에는 조금 더 알기 쉽게 fn 객체에 name 속성을 추가해보자.&#x20;

```javascript
var fn = {
    name: '함수',
    show
}

console.log(fn) // {name: "함수", show: ƒ}
```

그리고 fn.show() 함수를 실행시켜 보자 과연 this가 어떻게 출력될 것인가?&#x20;

```javascript
fn.show() 

// 출력되는 값 
// {name: "함수", show: ƒ}
```

방금 위에서 fn을 출력했을 때 값과 같다.&#x20;
{% endhint %}

이번엔 실행 주체를 다르게 해서 알아보자.&#x20;

아래 구문에서 this는 window이다.&#x20;

```javascript
window.show()
// Window {0: global, window: Window, self: Window, document: document, name: "", location: Location, …}

show()
// Window {0: global, window: Window, self: Window, document: document, name: "", location: Location, …}
```

call()메서드를 사용해서 this를 document로 바꿔보자. 출력되는 this의 값은 document이다.&#x20;

```javascript
show.call(document)
// #document
```

이번엔 시간차를 두고 콜백 함수에서 show() 함수를 실행시켜 보자.&#x20;

```javascript
window.setTimeout(() => {
    console.log(this)
})

// window 객체가 출력된다. ( 함수 실행 주체이기 때문이다. )
// Window {0: global, window: Window, self: Window, document: document, name: "", location: Location, …}

window.setTimeout(() => {
    fn.show()
})

// fn 객체가 출력된다. ( 함수 실행 주체이기 때문이다. )
// {name: "함수", show: ƒ}

window.setTimeout(() => {
    console.log(fn.show)
})

// show 함수가 출력된다. 함수 참조이다. 
// ƒ show() {
//     console.log(this)
// }
```

### 1.1 중간 정리

```javascript
const show = function() {
    console.log(this)
}

var fn = {
    show
} 

fn.show // 함수 참조 
fn.show() // 함수 실행 
```

### 1.2 단순호출과 엄격 모드&#x20;

#### 1.2.1 단순 호출&#x20;

함수를 실행 주체 없이 실행하면 `window`가 `this`로 출력된다. 사실 실행되는 주체가 설정되어 있지 않기 때문에 `undefined`로 출력 되야 하지만  것이 맞다. 하지만 이는 자바 스크립트의 기억해야 하는 특징 중에 하나이다.&#x20;

```javascript
function show() {
    console.log(this)
}

show()
// Window {0: global, window: Window, self: Window, document: document, name: "", location: Location, …}
```

#### 1.2.2 엄격 모드&#x20;

`'use strict'`를 사용하면 엄격하게 관리가 가능하다. 이를 사용하면 원래 함수의 실행 주체가 없으면 `undefined`로 나온다.&#x20;

```javascript
// IIFE 패턴 사용 
(function showValue() {
    'use strict'
    function show() {
        console.log(this)
    }
    return show() 
})()

// undefined

// 일반 함수 사용 
function show() {
    'use strict'
    console.log(this)
}

show() // undefined
```

## 2. 클래스에서 this&#x20;

객체 지향 클래스에서 `this`는 인스턴스를 가리킨다.&#x20;

```javascript
class Text {
    method() {
        this?.wow() 
    }
    wow() {
        console.log('wow')
    }
}


const t = new Text()

t.method() // wow 
```

## 3. 이벤트 핸들링에서 this&#x20;

{% hint style="info" %}
아래 예시와 모든 설명은 클래스 컴포넌트를 기준으로 이벤트 핸들링을 설명한 내용이다.&#x20;
{% endhint %}

### 3.1 일반 함수

React의 이벤트 핸들링에서  화살표 함수가 아닌 일반 함수를 사용하면 어떤 일이 일어나는지 보자.&#x20;

일반 함수를 이벤트 요소에 바인딩 했을 때 this를 출력해보니 undefined가 나온다. 왜? \
먼저 clickMethod 함수식을 보고 this를 예측해보자. this는 무엇이 나올까? 그렇다. undefined가 나온다. 함수를 실행시키는 주체가 없기 때문이다.&#x20;

자 그럼 다음 단계로 button 요소에 바인딩된 형태를 보자. 함수식이 참조 되어 있다. 그렇기 때문에 이벤트가 실행 되었을 때 clickMethod가 실행 되었을 때 출력되는 this의 값인 undefined가 그대로 나오는 것이다. 즉, 함수가 실행되는 주체를 찾을 수 없다. 아니 더 정확하게 말하면 찾을 수 없다기 보다 아예 없다.&#x20;

![](https://831271375-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSRg9KgNRIGErVFy_6g%2F-MT_fbhT5B2y1rKK2xWj%2F-MT_kN87kwfyy2aES2va%2Fimage.png?alt=media\&token=b784ee17-885a-4100-843e-b1bb12777813)

### &#x20;3.1.1 setTimeout() 사용&#x20;

첫 번째 출력된 값은 setTimeout()을 실행시키는 주체인 window가 출력되었다.  두 번째 출력된 값은 왜 아래 이미지와 같은 에러 메세지가 뜰까? 첫 번째 출력 값에서 알 수 있듯이 this는 window이다. 하지만 clickMethod()는 window 객체가 갖고 있는 메서드가 아니다. 그렇기 때문에 아래와 같이 함수가 아니라고 경고 메세지가 뜬다.&#x20;

![](https://831271375-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSRg9KgNRIGErVFy_6g%2F-MT_rl7fL9O12y8-TtHg%2F-MT_tLRxpVsulvdBdpjy%2Fimage.png?alt=media\&token=06cd1b76-56b2-4615-8288-52851bd97938)

###

### 3.2 화살표 함수&#x20;

이번엔 화살표 함수를 보자. 화살표 함수에서 this는 상위 컨텍스트의 this를 가리킨다. 아래 이미지의 표시된 상위 컨텍스트의 this는 무엇인가? 그렇다. App Element이다.&#x20;

![](https://831271375-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSRg9KgNRIGErVFy_6g%2F-MT_fbhT5B2y1rKK2xWj%2F-MT_n_ymkpUpcOSR59SO%2Fimage.png?alt=media\&token=8cd0418e-021a-47eb-b494-0dedada3c9f4)

### 3.2.1 setTimeout() 사용&#x20;

setTimeout()에 화살표 함수를 사용했다. 이는 this가 상위 컨텍스트를 가리킨다는 것이다. 그렇기 때문에 아래와 같이 상위 컨텍스트의 this인 App이 출력되는 것이다.&#x20;

![](https://831271375-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSRg9KgNRIGErVFy_6g%2F-MT_rl7fL9O12y8-TtHg%2F-MT_ukc1ZEBn0yCxUIhN%2Fimage.png?alt=media\&token=f9de0502-d7a7-4218-9882-f4d3fe089323)

### 3.3 render() 안의 this

render() 안의 this는 무엇일까? this는 App이 나온다. 왜냐하면 render()메서드는 인스턴스 객체인 App 컴포넌트의 멤버이자 메서드이기 때문이다.&#x20;

```javascript
import React from "react";
import "./style.css";

export default class App extends React.Component {

  render() {
    console.log(this);

    return ( ** );
  }
}
```

![](https://831271375-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MSRg9KgNRIGErVFy_6g%2F-MT_rl7fL9O12y8-TtHg%2F-MT_sb00e7-dDl5865Wg%2Fimage.png?alt=media\&token=f611f435-139b-4181-af6c-97a3aa1c40dd)
