Варианты использования: #
-приватные поля
Предисловие:
приватные и приватные во время выполнения
#
-приватные поля обеспечивают компиляцию время и конфиденциальность во время выполнения, которая не является "взломанной". Это механизм, который запрещает доступ к члену вне тела класса любым прямым способом .
class A {
#a: number;
constructor(a: number) {
this.#a = a;
}
}
let foo: A = new A(42);
foo.#a; // error, not allowed outside class bodies
(foo as any).#bar; // still nope.
Безопасное наследование класса
#
-приватные поля получить уникальный охват. Иерархии классов могут быть реализованы без случайной перезаписи частных свойств с одинаковыми именами.
class A {
#a = "a";
fnA() { return this.#a; }
}
class B extends A {
#a = "b";
fnB() { return this.#a; }
}
const b = new B();
b.fnA(); // returns "a" ; unique property #a in A is still retained
b.fnB(); // returns "b"
Компилятор TS, к счастью, выдает ошибку, когда private
свойства могут быть перезаписаны (см. в этом примере ). Но из-за особенностей функции времени компиляции все еще возможно во время выполнения, учитывая, что ошибки компиляции игнорируются и / или испускаются JS используемый код.
Внешние библиотеки
Библиотека авторы могут рефакторировать #
-приватные идентификаторы, не вызывая серьезных изменений для клиентов Пользователи библиотеки с другой стороны защищены от доступа к внутренним полям.
JS API пропускает #
-приватные поля
Встроенные JS функции и методы игнорируют #
- частные поля. Это может привести к более предсказуемому выбору свойств во время выполнения. Примеры: Object.keys
, Object.entries
, JSON.stringify
, for..in
l oop и другие ( пример кода ; см. Также ответ Мэтта Бирнера ):
class Foo {
#bar = 42;
baz = "huhu";
}
Object.keys(new Foo()); // [ "baz" ]
Варианты использования: private
ключевое слово
Предисловие:
Доступ к внутреннему API класса и состоянию (конфиденциальность только во время компиляции)
private
членов класса являются обычными свойствами во время выполнения. Мы можем использовать эту гибкость для доступа к внутреннему API-интерфейсу класса или состоянию извне. Для выполнения проверок компилятором могут использоваться такие механизмы, как утверждения типа, доступ к свойству Dynami c или @ts-ignore
.
Пример с утверждением типа (as
/ * Типизированное присвоение переменных 1082 *) и any
:
class A {
constructor(private a: number) { }
}
const a = new A(10);
a.a; // TS compile error
(a as any).a; // works
const casted: any = a; casted.a // works
TS даже разрешает динамический c доступ к свойству private
члена с escape-hatch :
class C {
private foo = 10;
}
const res = new C()["foo"]; // 10, res has type number
Где может иметь смысл частный доступ? (1) модульные тесты, (2) ситуации отладки / ведения журнала или (3) другой расширенный сценарий ios с внутренними классами проекта (открытый список).
Доступ к внутренним переменным немного противоречив, иначе вы бы не сделали их private
во-первых. В качестве примера, модульные тесты должны быть черными / серыми блоками с закрытыми полями, скрытыми как детали реализации. Однако на практике могут существовать подходы от случая к случаю.
Доступно во всех средах ES * Модификаторы
TS private
могут использоваться со всеми целями ES. #
-приватные поля доступны только для target
ES2015
/ ES6
или выше. В ES6 + WeakMap
используется внутри как реализация нижнего уровня (см. здесь ). Собственные #
-приватные поля в настоящее время требуют target
esnext
.
Согласованность и совместимость
Команды могут использовать правила кодирования и правила линтера, чтобы обеспечить использование private
как единственного модификатор доступа. Это ограничение может помочь с согласованностью и избежать путаницы с нотацией #
-приватного поля обратно совместимым способом.
При необходимости свойства параметра (сокращение назначения конструктора) являются демонстрацией стопор. Их можно использовать только с ключевым словом private
, и пока нет планов для их реализации для #
-приватных полей.
Другие причины
-
private
может обеспечить лучшую производительность во время выполнения в некоторых случаях понижения (см. здесь ). - В настоящее время в TS нет доступных методов закрытого частного класса.
- Некоторым людям лучше нравится
private
ключевое слово keyword.
Примечание на оба
Оба подхода создают некий номинальный или фирменный тип во время компиляции.
class A1 { private a = 0; }
class A2 { private a = 42; }
const a: A1 = new A2();
// error: "separate declarations of a private property 'a'"
// same with hard private fields
Кроме того, оба допускают доступ между экземплярами: экземпляр класса A
может получить доступ к закрытым членам других A
экземпляров:
class A {
private a = 0;
method(arg: A) {
console.log(arg.a); // works
}
}
Источники