TypeScript Deep Dive
  • README
  • 시작하기
    • 왜 타입스크립트인가
  • 자바스크립트
    • 비교 연산자
    • 참조 연산자
    • Null vs. Undefined
    • this
    • 클로저
    • Number
    • Truthy
  • 미래의 자바스크립트
    • 클래스
      • 즉시실행함수
    • 화살표 함수
    • 나머지 연산자
    • let
    • const
    • 비구조화 할당
    • 전개 연산자
    • for...of
    • 이터레이터
    • 템플릿 리터럴
    • 프로미스
    • 제네레이터
    • Async Await
  • 프로젝트
    • 컴파일러 제어
      • tsconfig.json
      • 파일 경로 지정
    • 선언
    • 모듈화
      • 파일을 이용한 모듈화
      • globals.d.ts
    • 네임스페이스
    • 동적 표현식 가져오기
  • Node.js 시작하기
  • Browser 시작하기
  • 타입스크립트 타입 시스템
    • 자바스크립트 마이그레이션 가이드
    • @types
    • 주변 선언
      • 파일 선언
      • 변수
    • 인터페이스
    • 열거형(Enums)
    • lib.d.ts
    • 함수
    • 콜러블(Callable)
    • 타입 표명(Type Assertion)
    • 신선도(Freshness)
    • 타입 가드
    • 리터럴(Literal)
    • 읽기 전용(readonly)
    • 제네릭
    • 타입 인터페이스
    • 타입 호환성
    • Never 타입
    • 구별된 유니온
    • 인덱스 서명(Index Signature)
    • 타입 이동하기
    • 예외 처리
    • 믹스인(Mixin)
  • JSX
    • React
    • Non React JSX
  • Options
    • noImplicitAny
    • strictNullChecks
  • 타입스크립트 에러
    • 에러 메세지
    • 공통 에러
  • NPM
  • 테스트
    • Jest
    • Cypress
  • Tools
    • Prettier
    • Husky
    • ESLint
    • Changelog
  • 팁
    • 문자열 Enums
    • 타입 단언
    • 상태 저장 함수
    • 커링
    • 제네릭 타입 예시
    • 객체 타입 설정
    • 유용한 클래스
    • Import / Export
    • 속성 Setters
    • outFile 주의사항
    • 제이쿼리 팁
    • 정적 생성자
    • 싱글톤 패턴
    • 함수 파라미터
    • 토글 생성
    • Import 여러개 하기
    • 배열 생성
    • 생성자에서 타입정의
  • 스타일 가이드
  • 타입스크립트 컴파일러 구조
    • Program
    • AST
      • TIP: Visit Children
      • TIP: SyntaxKind enum
      • Trivia
    • Scanner
    • Parser
      • Parser Functions
    • Binder
      • Binder Functions
      • Binder Declarations
      • Binder Container
      • Binder SymbolTable
      • Binder Error Reporting
    • Checker
      • Checker Diagnostics
      • Checker Error Reporting
    • Emitter
      • Emitter Functions
      • Emitter SourceMaps
    • Contributing
Powered by GitBook
On this page
  • 즉시실행함수는 무엇인가?
  • __extends
  • d.prototype.__proto__ = b.prototype
  • d.prototype.__proto__ = b.prototype 중요성

Was this helpful?

  1. 미래의 자바스크립트
  2. 클래스

즉시실행함수

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

클래스에 의해 생성된 js는

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)
}

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

;(function() {
    // BODY

    return Point
})()

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

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

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

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입니다. 이것은 자바스크립트가 프로토타입 상속을 즉시 지원하는 이유를 설명합니다. 다음에 나오는 예제는 크롬 콘솔 또는 노드에서 실행해 볼 수 있습니다.

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를 포함하고 있습니다. 아래에서 확인할 수 있습니다.

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를 변경하면 간단합니다.

function Foo() {
    this.bar = 123
}

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

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

function Foo() {}

var foo = new Foo()

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

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

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 중요성

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

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)

Previous클래스Next화살표 함수

Last updated 5 years ago

Was this helpful?