# 즉시실행함수

### 즉시실행함수는 무엇인가?

클래스에 의해 생성된 js는

```typescript
function Point(x, y) {
    this.x = x
    this.y = y
}
Point.prototype.add = function(point) {
    return new Point(this.x + point.x, this.y + point.y)
}
```

즉시실행함수가 랩핑된 이유는

```typescript
;(function() {
    // BODY

    return Point
})()
```

상속과 관련이 있습니다. 타입스크립트를 사용하여 기본 클래스를 `_super`와 같은 변수로 캡쳐할 수 있습니다.

```typescript
var Point3D = (function(_super) {
    __extends(Point3D, _super)
    function Point3D(x, y, z) {
        _super.call(this, x, y)
        this.z = z
    }
    Point3D.prototype.add = function(point) {
        var point2D = _super.prototype.add.call(this, point)
        return new Point3D(point2D.x, point2D.y, this.z + point.z)
    }
    return Point3D
})(Point)
```

즉시실행함수를 통해 타입스크립트가 `_super`변수에서 기본 클래스 `Point`를 쉽게 캡쳐할 수 있으며 클래스 본문에서 일관되게 사용하는 점에 유의하십시요.

## `__extends`

클래스를 상속하는 즉시 타입스크립트는 다음 기능도 생성됨을 알수 있습니다.

```typescript
var __extends =
    this.__extends ||
    function(d, b) {
        for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]
        function __() {
            this.constructor = d
        }
        __.prototype = b.prototype
        d.prototype = new __()
    }
```

여기서 `d`는 파생 클래스를 참조하고 `b`는 기본 클래스를 참조합니다. 이 함수는 두가지 작업을 수행합니다.

1. 기본 클래스의 정적멤버를 하위클래스로 복사 `for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];`
2. 자식클래스 함수의 프로토타입을 설정하여 선택적으로 부모의 `proto`에 있는 멤버를 조회합니다. `d.prototype.__proto__ = b.prototype`

사람들은 거의 이해하는데 어려움을 겪지만 그러나 2번 순서의 이유에 대해 많은 사람들이 힘들어 합니다.

### `d.prototype.__proto__ = b.prototype`

이것에 대해 많은 사람들을 가르친후에야 나는 다음과 같은 설명이 가장 단순한 것을 알게되었습니다. 먼저 `__extends`의 코드가 `d.prototype.__proto__ = b.prototype`와 같은지 설명하고 이 모든 것을 이해하려면 다음사항을 알아야 합니다.

1. `__proto__`
2. `prototype`
3. effect of `new` on `this` inside the called function
4. effect of `new` on `prototype` and `__proto__`

자바스크립트의 모든 객체는 `__proto__`안에 있는 멤버입니다. 이 멤버는 오래된 브라우저에서는 접근할 수 없는 경우가 많이 있습니다. (때때로 문서에서는 `[[prototype]]`과 같은 마법같은 속성을 참조합니다). 그것은 하나의 목표를 가지고 있습니다. 검색중에 `obj.property` 객체에 속성이 없으면 `obj.__proto__.property`에서 찾습니다. 그래도 없다면 `obj.__proto__.__proto__.property`에서 찾습니다. 그러면 발견되거나 최신 `.__proto__` 자체가 null입니다. 이것은 자바스크립트가 프로토타입 상속을 즉시 지원하는 이유를 설명합니다. 다음에 나오는 예제는 크롬 콘솔 또는 노드에서 실행해 볼 수 있습니다.

```typescript
var foo = {}

// setup on foo as well as foo.__proto__
foo.bar = 123
foo.__proto__.bar = 456

console.log(foo.bar) // 123
delete foo.bar // remove from object
console.log(foo.bar) // 456
delete foo.__proto__.bar // remove from foo.__proto__
console.log(foo.bar) // undefined
```

이제 당신은 `__proto__`을 이해하게 되었습니다. 또하나 유용한 사실은 자바스크립트의 모든 `function`의 속성은 `prototype`그리고 멤버 `constructor`를 포함하고 있습니다. 아래에서 확인할 수 있습니다.

```typescript
function Foo() {}
console.log(Foo.prototype) // {} i.e. it exists and is not undefined
console.log(Foo.prototype.constructor === Foo) // Has a member called `constructor` pointing back to the function
```

이제 `new`를 이용해서 생성된 함수가 호출된 함수내부에서 어떤 영향을 미치는지 알아보겠습니다. 근본적으로 `this`는 함수내부에서 호출할 때 생성되고 함수를 반환하고 함수내부에서 `this`를 변경하면 간단합니다.

```typescript
function Foo() {
    this.bar = 123
}

// call with the new operator
var newFoo = new Foo()
console.log(newFoo.bar) // 123
```

이제 함수에서 `new`를 호출하면 함수 호출에서 반한된 새로 생성된 객체에 `__proto__`에 함수의 `prototype`이 할당 된다는 점을 알아야 합니다. 완전히 이해하기 위해 실행할 수 있는 코드가 여기에 있습니다.

```typescript
function Foo() {}

var foo = new Foo()

console.log(foo.__proto__ === Foo.prototype) // True!
```

이제 다음과 같은 `__extends`를 살펴보십시요 그게 전부입니다.

```typescript
1  function __() { this.constructor = d; }
2   __.prototype = b.prototype;
3   d.prototype = new __();
```

이 함수를 역순으로 읽으면 `d.prototype = new __()`는 `d.prototype = {__proto__ : __.prototype}`임을 의미합니다. (왜냐하면 `new`와 `prototype`는 `__proto__`안에 있으므로) 이전 줄과 결합하여 (예: 2번째 줄 `__.prototype = b.prototype;`)과 결합하여 `d.prototype = {__proto__ : b.prototype}`을 얻습니다.

그러나 잠깐 우리는 `d.prototype.__proto__`을 원했습니다. 그러나 오래된 proto가 변경되고 `d.prototype.constructor`를 유지합니다. 이것은 첫번째 줄에 (예: `function __() { this.constructor = d; }`) 들어옵니다. 여기서 우리는 효과적으로 `d.prototype = {__proto__ : __.prototype, constructor : d}` (`new`에 `this`를 가질 것 입니다.) 그래서 우리가 `d.prototype.constructor`를 복원했으므로 진정으로 변이시킨 것은 `__proto__` 따라서 `d.prototype.__proto__ = b.prototype` 입니다.

### `d.prototype.__proto__ = b.prototype` 중요성

중요한 점은 하위 클래스에 멤버 함수를 추가하고 기본 클래스에서 다른 멤버를 상속할 수 있다는 것 입니다. 이것은 다음의 간단한 예제에 의해 증명됩니다.

```typescript
function Animal() {}
Animal.prototype.walk = function() {
    console.log('walk')
}

function Bird() {}
Bird.prototype.__proto__ = Animal.prototype
Bird.prototype.fly = function() {
    console.log('fly')
}

var bird = new Bird()
bird.walk()
bird.fly()
```

기본적으로 `bird.fly`은 `bird.__proto__.fly`을 검색합니다. (`new`를 이용해서 생성하면 `bird.__proto__`에 `Bird.prototype`가 할당되는 것을 기억하고 있나요?) 그리고 `bird.walk`(상속 멤버는) 다음을 통해서 검색할 수 있습니다. `bird.__proto__.__proto__.walk` (as `bird.__proto__ == Bird.prototype` 그리고 `bird.__proto__.__proto__` == `Animal.prototype`)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://radlohead.gitbook.io/typescript-deep-dive/future-javascript/classes/classes-emit.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
