typescript
GitHub
  • README
  • Давайте Почнемо
    • Why TypeScript
  • JavaScript
    • Equality
    • References
    • Null vs. Undefined
    • this
    • Closure
    • Number
    • Truthy
  • Future JavaScript Now
    • Classes
      • Classes Emit
    • Arrow Functions
    • Rest Parameters
    • let
    • const
    • Destructuring
    • Spread Operator
    • for...of
    • Iterators
    • Template Strings
    • Promise
    • Generators
    • Async Await
  • Проект / Project
    • Контекст компіляції / Compilation Context
      • tsconfig.json
      • Які файли / Which Files?
    • Простори Оголошень / Declaration Spaces
    • Модулі / Modules
      • File Module Details
      • global.d.ts
    • Namespaces
    • Dynamic Import Expressions
  • Node.js QuickStart
  • Browser QuickStart
  • Library QuickStart
  • TypeScript's Type System
    • JS Migration Guide
    • @types
    • Ambient Declarations
      • Declaration Files
      • Variables
    • Interfaces
    • Enums
    • lib.d.ts
    • Functions
    • Callable
    • Type Assertion
    • Freshness
    • Type Guard
    • Literal Types
    • Readonly
    • Generics
    • Type Inference
    • Type Compatibility
    • Never Type
    • Discriminated Unions
    • Index Signatures
    • Moving Types
    • Exception Handling
    • Mixins
  • JSX
    • React
    • Non React JSX
  • Options
    • noImplicitAny
    • strictNullChecks
  • Errors in TypeScript
    • Interpreting Errors
    • Common Errors
  • NPM
  • Testing
    • Jest
    • Cypress
  • Tools
    • Prettier
    • Husky
    • ESLint
    • Changelog
  • TIPs
    • String Based Enums
    • Nominal Typing
    • Stateful Functions
    • Currying
    • Type Instantiation
    • Lazy Object Literal Initialization
    • Classes are Useful
    • Avoid Export Default
    • Limit Property Setters
    • outFile caution
    • JQuery tips
    • static constructors
    • singleton pattern
    • Function parameters
    • Build Toggles
    • Barrel
    • Create Arrays
    • Typesafe Event Emitter
  • StyleGuide
  • TypeScript Compiler Internals
    • 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
Edit on GitHub
  1. Future JavaScript Now

Classes

PreviousFuture JavaScript NowNextClasses Emit

Last updated 2 years ago

Classes

Причина, чому важливо мати класи в JavaScript як елемент першого класу, полягає в тому, що:

  1. Забезпечують послідовний спосіб для розробників використовувати класи замість кожного фреймворку (emberjs, reactjs тощо), створюючи власну версію.

  2. Об'єктно-орієнтовані розробники вже розуміють класи

Нарешті розробники JavaScript можуть мати class. Як приклад, ми маємо базовий клас під назвою Point:

class Point {
    x: number;
    y: number;
    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }
    add(point: Point) {
        return new Point(this.x + point.x, this.y + point.y);
    }
}

var p1 = new Point(0, 10);
var p2 = new Point(10, 20);
var p3 = p1.add(p2); // {x:10,y:30}

Цей клас генерує наступний JavaScript, грунтуючись на ES5:

var Point = (function () {
    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);
    };
    return Point;
})();

Це досить ідіоматичний традиційний шаблон класу JavaScript, який тепер є мовною конструкцією першого класу.

Inheritance

Наслідування.

Класи в TypeScript (як і в інших мовах) підтримують single наслудування (у класа може бути ліше один батьківський клас) за допомогою ключового слова extends, як показано нижче:

class Point3D extends Point {
    z: number;
    constructor(x: number, y: number, z: number) {
        super(x, y);
        this.z = z;
    }
    add(point: Point3D) {
        var point2D = super.add(point);
        return new Point3D(point2D.x, point2D.y, this.z + point.z);
    }
}

Якщо у вашому класі є конструктор, ви повинні викликати батьківський конструктор із свого конструктора (TypeScript вкаже вам на це). Це гарантує, що все, що потрібно для існування класу та ініціалізації this, буде встановлено. Після виклику super ви можете додати будь-які додаткові речі, які ви хочете зробити у вашому конструкторі (тут ми додаємо ще один член z). Зауважте, що ви легко замінюєте батьківські функції-члени (тут ми перевизначаємо add ) і все ще використовуємо функціональність суперкласу у своїх членах (використовуючи синтаксис super. ).

Statics

Статичні властивості класу.

Класи TypeScript підтримують статичні властивості, які є спільними для всіх екземплярів класу. Природним місцем для їх розміщення (і доступу) є сам клас, і саме це робить TypeScript:

class Something {
    static instances = 0;
    constructor() {
        Something.instances++;
    }
}

var s1 = new Something();
var s2 = new Something();
console.log(Something.instances); // 2

Ви можете мати як статичні члени, так і статичні функції.

Access Modifiers

Модифікатори доступу.

TypeScript підтримує модифікатори доступу public (публічний),private (приватний) та protected (захищений), які визначають доступність члена класу , як показано нижче:

доступні для

public

protected

private

клас

так

ні

так

дочерний клас

так

так

ні

екземпляр класу

так

ні

ні

Якщо модифікатор доступу не вказано, він неявно відкритий, оскільки це відповідає зручному характеру JavaScript 🌹.

Зверніть увагу, що під час виконання (у згенерованому JS) вони не мають значення, але викличуть помилки під час компіляції, якщо ви використовуєте їх неправильно. Приклад кожного показаний нижче:

class FooBase {
    public x: number;
    private y: number;
    protected z: number;
}

// EFFECT ON INSTANCES
var foo = new FooBase();
foo.x; // okay
foo.y; // ERROR : private
foo.z; // ERROR : protected

// EFFECT ON CHILD CLASSES
class FooChild extends FooBase {
    constructor() {
      super();
        this.x; // okay
        this.y; // ERROR: private
        this.z; // okay
    }
}

Як завжди, ці модифікатори працюють як для властивостей члена, так і для функцій члена.

Abstract

Абстрактний клас.

abstract можна розглядати як модифікатор доступу. Ми представляємо його окремо, тому що, на відміну від згаданих раніше модифікаторів, він може бути як у class, так і в будь-якому члені класу. Наявність abstract модифікатора в першу чергу означає, що така функціональність не може бути безпосередньо викликана , і дочірній клас повинен надавати цю функціональність.

  • Ми не можемо створити екземпляр abstract classes. Замість цього користувач повинен створити якийсь class, який наслідує від abstract class

abstract class FooCommand {}

class BarCommand extends FooCommand {}

const fooCommand: FooCommand = new FooCommand(); // Не можно створити екземпляр (instance) класу
const barCommand = new BarCommand(); // Можно створити екземпляр класу, який є потомком абстрактного класу
  • неможливо отримати прямий доступ доabstract members, тому дочірній клас повинен забезпечувати цю функціональність.

abstract class FooCommand {
  abstract execute(): string;
}

class BarErrorCommand  extends FooCommand {} // 'BarErrorCommand' повинен реалізувати'execute'.

class BarCommand extends FooCommand {
  execute() {
    return `Command Bar executed`;
  }
}

const barCommand = new BarCommand();

barCommand.execute(); // Command Bar executed

Constructor is optional

Конструктор класу необов'язковий.

Клас не потребує наявності конструктора. наприклад, наступне цілком нормально. Якщо не створити конструктор власноруч, TypeScript зробить конструктор за замовчуванням

class Foo {}
var foo = new Foo();

Define using constructor

Визначення властивості за допомогою конструктора.

Наявність члена в класі та його ініціалізація, як показано нижче:

class Foo {
    x: number;
    constructor(x:number) {
        this.x = x;
    }
}

є настільки поширеним шаблоном, що TypeScript надає скорочення, де ви можете додати до члена access modifier, і він автоматично оголошується в класі та копіюється з конструктора. Тож попередній приклад можна переписати таким чином (зверніть увагу на public x:number ):

class Foo {
    constructor(public x:number) {
    }
}

Property initializer

Ініціалізатор властивості.

Це чудова функція, яка підтримується TypeScript (з ES7). Ви можете ініціалізувати будь-який член класу поза конструктором класу, що корисно для встановлення значення за замовчуванням (зверніть увагу на number = [] )

class Foo {
    members = [];  // Initialize directly
    add(x) {
        this.members.push(x);
    }
}
Класи пропонують корисну структурну абстракцію