Почему я могу получить доступ к закрытым членам TypeScript, хотя у меня нет такой возможности?

StackOverflow https://stackoverflow.com//questions/12713659

  •  13-12-2019
  •  | 
  •  

Вопрос

Я смотрю на реализацию частных членов в TypeScript и нахожу это немного запутанным.Intellisense не позволяет получить доступ к частному члену, но в чистом JavaScript все это есть.Это заставляет меня думать, что TS неправильно реализует частные члены.Есть предположения?

class Test{
  private member: any = "private member";
}
alert(new Test().member);
Это было полезно?

Решение

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

Частная собственность реализуется как регулярное свойство, а код вне класса не допускается доступа к нему.

Чтобы сделать что-то по-настоящему частное внутри класса, он не может быть членом класса, это будет локальная переменная, созданная внутри функциональной массы внутри кода, который создает объект.Это означало бы, что вы не можете получить доступ к нему, как член класса, то есть с использованием ключевого слова this.

Другие советы

JavaScript поддерживает частные переменные.

function MyClass() {
    var myPrivateVar = 3;

    this.doSomething = function() {
        return myPrivateVar++;        
    }
}
.

в Teadercript Это будет выражено так:

class MyClass {

    doSomething: () => number;

    constructor() {
        var myPrivateVar = 3;

        this.doSomething = function () {
            return myPrivateVar++;
        }
    }
}
.

Редактировать

Этот подход должен использоваться только экономно , где он абсолютно необходим.Например, если вам нужно временно кэшировать пароль.

Есть затраты на производительность для использования этой структуры (неактуальны JavaScript или Teadercript) и должны использоваться только в том случае, если это абсолютно необходимо.

После поддержки для SolidMap большеШироко доступно, есть интересная техника, детализированная в примере # 3 Здесь ,

Это позволяет для частных данных и избежать затрат на производительность примера Джейсона Эванса, что позволив данные доступны из методов прототипа вместо только методов экземпляра.

Связанная страница страниц MDN ScaleMap перечислена поддержка браузера на Chrome 36, Firefox 6.0, IE 11, Opera 23 и Safari 7.1.

let _counter = new WeakMap();
let _action = new WeakMap();
class Countdown {
  constructor(counter, action) {
    _counter.set(this, counter);
    _action.set(this, action);
  }
  decrement() {
    let counter = _counter.get(this);
    if (counter < 1) return;
    counter--;
    _counter.set(this, counter);
    if (counter === 0) {
      _action.get(this)();
    }
  }
}
.

Благодаря Шону Фельдману по ссылке на официальную дискуссию по этому вопросу - см. его ответ для ссылки.

Я прочитал обсуждение, которому он связал, и вот резюме ключевых моментов:

    .
  • Предложение: Частные свойства в конструкторе
      .
    • Проблемы: не может получить доступ к функциям прототипа
  • Предложение: Частные методы в конструкторе
      .
    • Проблемы: То же, что и со свойствами, плюс вы теряете эффективность создания функции один раз за класс в прототипе; Вместо этого вы создаете копию функции для каждого экземпляра
  • Предложение: Добавить бойную таблицу в абстрактный доступ к недвижимости и обеспечить видимость
      .
    • Проблемы: Основные характеристики накладных расходов; Shotescript предназначен для больших приложений
  • Предложение: TypeScript TypeScript, уже оборачивает определения метода конструктора и прототипа в закрытии; Поместите частные методы и свойства там
      .
    • Проблемы с привлечением частных свойств в этом закрытии: они становятся статическими переменными; Там нет одного за экземпляр
    • Проблемы с установлением частных методов в этом закрытии: у них нет доступа к this без какого-либо обходного пути
  • Предложение: Автоматически слеглите названия частных переменных
      .
    • Счетчик аргументов: Это соглашение об именах, а не языковая конструкция. Убейте это сами
  • Предложение: Аннотация Частные методы с @private To Minifiers, которые распознают, что аннотация может эффективно минифицировать имена методов
      .
    • Нет значимых противоречивых аргументов к этому

Общие контрварки для добавления поддержки видимости в испускаемом коде:

    .
  • Проблема в том, что сам JavaScript не имеет модификаторов видимости - это не проблема типографии
  • уже есть установленный узел в сообществе JavaScript: префикс частных свойств и методов с подчеркиванием, который говорит «Продолжить свой риск»
  • , когда Teartcript Designers заявили, что действительно частные свойства и методы не «возможно», они имели в виду «невозможен под нашими проектами», в частности:
      .
    • излучаемые js идиоматичны
    • Boeterplate минимальна
    • Нет дополнительных накладных расходов по сравнению с обычными JS OOP

в типографии частные функции доступны только внутри класса.Как

 Введите описание изображения здесь

И это покажет ошибку, когда вы пытаетесь получить доступ к частному участнику.Вот пример:

 Введите описание изображения здесь

Примечание: все будет хорошо с JavaScript, и обе функции доступны снаружи.

Я понимаю, что это более старая дискуссия, но, возможно, было бы полезно поделиться своим решением проблемы предположительно частных переменных и методов в TypeScript, «просачивающихся» в общедоступный интерфейс скомпилированного класса JavaScript.

Для меня эта проблема чисто косметическая, т.е.все дело в визуальном беспорядке, когда переменная экземпляра просматривается в DevTools.Мое решение состоит в том, чтобы сгруппировать частные объявления внутри другого класса, который затем создается в основном классе и назначается private (но все еще общедоступная в JS) переменная с именем типа __ (двойное подчеркивание).

Пример:

class Privates {
    readonly DEFAULT_MULTIPLIER = 2;
    foo: number;
    bar: number;

    someMethod = (multiplier: number = this.DEFAULT_MULTIPLIER) => {
        return multiplier * (this.foo + this.bar);
    }

    private _class: MyClass;

    constructor(_class: MyClass) {
        this._class = _class;
    }
}

export class MyClass {
    private __: Privates = new Privates(this);

    constructor(foo: number, bar: number, baz: number) {
        // assign private property values...
        this.__.foo = foo;
        this.__.bar = bar;

        // assign public property values...
        this.baz = baz;
    }

    baz: number;

    print = () => {
        console.log(`foo=${this.__.foo}, bar=${this.__.bar}`);
        console.log(`someMethod returns ${this.__.someMethod()}`);
    }
}

let myClass = new MyClass(1, 2, 3);

Когда myClass экземпляр просматривается в DevTools, вместо того, чтобы видеть все его «частные» члены, смешанные с действительно общедоступными (что может стать очень визуально беспорядочным в правильно реорганизованном реальном коде), вы видите их аккуратно сгруппированными внутри свернутого экземпляра. __ свойство:

enter image description here

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top