2
import ws = require('ws');

export class Server
{
    public static instance:Server;
    private _webSocketServer: ws.Server;

    // подключенные клиенты
    private _clients: { [id: number]: ws; } = { };

    constructor()
    {
        if (Server.instance !== null && Server.instance !== undefined)
            throw new Error('singleton');

        Server.instance = this;

        this._webSocketServer = new ws.Server({ port: 8081 });
        this._webSocketServer.on('connection', this.onUserConnect);
        this._webSocketServer.on('error', this.onError);
    }

    private onUserConnect(client:ws): void
    {
        var id:number = Math.random();
        this._clients[id] = client;
        console.log("новое соединение " + id);

        //client.on('close', ServerGame.instance.onUserDisconnect);
        client.onclose = this.onUserDisconnect;
        client.onmessage = this.onUserMessage;
    }

Решил сделать сервер nodejs на typescript и разделить все по ООП по классам. Написал такой код в typescript в коннструкторе все хорошо... _clients инициализирована, но как только попадаю в onUserConnect то _clients уже undefined как и метод onUserConnect например. Т.е. ощущение что попал в другой пустой обхект какой то. а не тот экземпляр класса где был. Вопроса тут два:

  • моя ли тут ошибка(я новичок)? и как в такой схеме все поправить?

  • Может есть более правильный подход, где можно сделать хорошую структуру ООП без таких проблем.

Я пробовал ссылаться через синглтон и все работало но это как то грязно( Заранее спасибо за помощь!

  • Похоже у Вас в голове полная каша и Вы не понимаете базовые основы языка. Вы просто потеряли контекст в обработчике. Это js механизм, не уникальный для тайпскрипта. – Утка Учится Укрываться Sep 15 '16 at 18:30
  • 1
    Вам может помочь вот этот вопрос и ответы на него: http://ru.stackoverflow.com/questions/535030/%D0%9F%D0%BE%D1%82%D0%B5%D1%80%D1%8F-%D0%BA%D0%BE%D0%BD%D1%82%D0%B5%D0%BA%D1%81%D1%82%D0%B0-%D0%B2%D1%8B%D0%B7%D0%BE%D0%B2%D0%B0/ – Утка Учится Укрываться Sep 15 '16 at 18:30
  • каша в голове это понятно...я пришел из другого языка, где такого поведения не было бы. Мне помощь нужна как тут все организовать) – voidmain Sep 15 '16 at 18:35
  • Функции в js - объекты первого класса. когда вы делаете smth.on('event', handler), вы передаете сам хендлер без привязки к контексту. Почитайте ответы по ссылке выше что я привел, там тот же самый вопрос только без лишнего. Проблема "потери контекста" типичная для начинающих в js и объясняется примерно в каждом учебнике по js, например тут: http://learn.javascript.ru/objects-more – Утка Учится Укрываться Sep 15 '16 at 18:38
  • я в принципе понимаю, что теряется контекст, но не понимаю как передать колбэк с сохранением контекста. можете дать показать простой пример? Если я вызаваю метод call то это именно вызов а не передача метода как параметра. – voidmain Sep 15 '16 at 18:47
  • this.onUserConnect.bind(this), плюс еще есть стрелочные функции. Это в самом js. Может в тайпскрипте еще что есть, я его не знаю. – Утка Учится Укрываться Sep 15 '16 at 18:48
  • спасибо! будем посмотреть!:) – voidmain Sep 15 '16 at 19:00
  • @Утка, стоило проголосовать за закрытие дубликатом, а не просто ссылку ставить – Grundy Sep 15 '16 at 19:30
  • @Утка, я ща напишу, но не подробный :-) – Grundy Sep 15 '16 at 20:10

1 Answers1

1

TypeScript не лишен особенности Javascript при работе с this.

Подробнее о возможных причинах потери контекста можно посмотреть в ответах на соответствующий вопрос

Важное отличие TypeScript на данный момент в том, что он позволяет использовать стрелочные функции при определении членов класса не только в конструкторе, но и в самом теле класса. В JavaScript это пока возможно только в конструкторе.

class test{
    // Use arrow functions
    func1=(arg:string)=>{
            return arg+" yeah" + this.prop;
    }

    // some property on this
    prop = 10;
}

Online пример

Grundy
  • 81,538
  • "позволяет использовать стрелочные функции при определении методов класса" - неправда. Это просто инстансное поле, а не метод класса. – Qwertiy Sep 15 '16 at 21:04
  • @Qwertiy, да :-) не обратил на это внимание. Синтаксис чуть отличается. Как тогда лучше написать? – Grundy Sep 15 '16 at 21:07
  • А классический вариант с замыканием или bind'ом уже не вариант? – Qwertiy Sep 15 '16 at 21:08
  • @Qwertiy, вариант :-) именно поэтому я за дубликат голосовал. Здесь хотел именно добавить, что в самом теле класса можно стрелочные функции использовать. а не только в конструкторе, как в яваскрипте – Grundy Sep 15 '16 at 21:11
  • Но ведь при компиляции это в конструктор и отправится... – Qwertiy Sep 15 '16 at 21:12
  • @Qwertiy, в данном случае после компиляции что будет не важно, так как работа идет с typescript. Немного изменил формулировку. лучше стало? – Grundy Sep 15 '16 at 21:13