Контроль доступа в классах Typescript
Многие языки программирования по умолчанию определяют свойства своих классов как частные. Чтобы сделать их доступными извне, вам обычно нужно пометить соответствующие свойства ключевым словом «public».
Это же ключевое слово также доступно в классах Typescript, но не оказывает особого влияния, поскольку свойства в классах Typescript по умолчанию являются общедоступными. Это ограничение унаследовано от Javascript, который не поддерживает частные свойства в классах. Ну до недавнего времени.
Частные поля в Javascript?
И да и нет. В настоящее время рабочий черновик спецификации, определяющей частные свойства в классах Javascript, находится на этапе 3, что указывает на то, что окончательное определение правдоподобно, но еще не уверено.
Предлагаемые изменения в спецификации действительно просты и лишь незначительно изменяют синтаксис. Чтобы пометить свойство как частное, просто добавьте к нему хэштег. Это оно!
class User {
// A prop marked as private.
#id;
age;
constructor(age){
this.age = age;
// Valid assignment, as we're
// within the class.
this.#id = Math.floor(Math.random() * 1000);
}
}
// ... Later in the code ...
const user = new User(42);
// Error! Won't work as it's private.
user.#id = 123;
Частные поля в машинописном тексте!
Тот же самый синтаксис применяется к частным свойствам в Typescript. Начиная с версии 3.8, вы можете использовать эту функцию, чтобы лучше контролировать доступ к свойствам и функциям для экземпляров, а также к статическим полям. Синтаксис такой же, как в примере с Javascript.
Подождите, пожалуйста, частные статические поля?
Да, вы правильно прочитали: статические переменные, как и функции, также могут быть закрытыми, что означает, что они могут вызываться только внутри членов класса. Эта функция была добавлена в Typescript версии 4.3 вместе с дальнейшими внутренними изменениями. Согласно документации для версии 4.3, закрытые члены класса теперь действительно закрыты во время выполнения, что указывает на то, что эта функция полностью созрела.
Обратите внимание, что Typescript поддерживает два разных варианта "private" для классов. Наиболее широко известен вариант с ключевым словом "private", по которому отмеченные поля остаются недоступными даже для производных классов.
Другая особенность, которую я показываю здесь и которая является новой, - это использование так называемых «частных имен». У них тот же синтаксис, что и для Javascript, поскольку их спецификация изначально была определена JS. В Typescript они контролируют доступ во время выполнения.
/**
* A class that uses already known
* private props.
*/
class CommonUser {
// Common 'private' prop in TS.
private id: number;
age: number;
constructor(age: number){
this.age = age;
this.id = Math.floor(Math.random() * 1000);
}
}
/**
* Using the new sytanx for private class names.
*/
class SpecialUser {
#id: number;
age: number;
constructor(age: number){
this.age = age;
// Valid, we're inside the class.
this.#id = SpecialUser.#generateId();
}
static #generateId(){
return Math.floor(Math.random() * 1000);
}
#stringifyId(){
return this.#id.toString();
}
}
// ... Later in the code ...
// Invalid, call is outside of class 'SpecialUser'.
SpecialUser.#generateId();
const user = new SpecialUser(42);
// And that won't work as well.
user.#stringifyId();
Последние слова последней главы
Эта статья не очень длинная, но в ней освещаются замечательные возможности, которые сейчас предлагает Typescript, а также более общие преимущества самого Typescript. Для Javascript частные свойства все еще находятся в стадии черновика (хотя и на очень поздней стадии), но для Typescript они уже реализованы и отправлены, что показывает скорость, с которой развивается этот язык!