Ответ
В чистом JavaScript (ES6 и выше) нет встроенных модификаторов доступа, таких как private, но есть несколько паттернов для эмуляции приватных полей.
1. Приватные поля класса (современный стандарт, ES2022): Самый чистый и рекомендуемый способ. Поле становится недоступным за пределами класса.
class User {
#secretKey; // Приватное поле
name; // Публичное поле
constructor(name, key) {
this.name = name;
this.#secretKey = key;
}
getKeyHash() {
// Доступ к приватному полю возможен только внутри класса
return hashFunction(this.#secretKey);
}
}
const user = new User('Alice', 's3cr3t');
console.log(user.name); // 'Alice'
console.log(user.#secretKey); // SyntaxError: Private field '#secretKey' must be declared in an enclosing class
console.log(user.getKeyHash()); // Работает
2. Замыкания (Closures) в конструкторе функции или фабрике: Классический прием, обеспечивающий настоящую приватность.
function createUser(name) {
let _password = ''; // Приватная переменная, доступная только через замыкание
return {
name: name,
setPassword: (pw) => {
_password = pw;
},
validatePassword: (pw) => {
return _password === pw;
}
};
}
const user = createUser('Bob');
user.setPassword('123');
console.log(user.validatePassword('123')); // true
console.log(user._password); // undefined
3. Символы (Symbols) или WeakMaps (менее строгие методы): Эти методы скорее защищают от случайного доступа, чем от намеренного.
// С использованием WeakMap
const _privateData = new WeakMap();
class Logger {
constructor(logLevel) {
// Сохраняем приватные данные в WeakMap, используя экземпляр как ключ
_privateData.set(this, { level: logLevel, internalCounter: 0 });
}
log(message) {
const data = _privateData.get(this);
data.internalCounter++;
console.log(`[${data.level}] ${message} (call #${data.internalCounter})`);
}
}
Вывод: Да, скрыть поля можно. Для современного кода на Node.js используйте синтаксис приватных полей класса (#field). Для максимальной изоляции в функциональном стиле подходят замыкания.