Ответ
В чистом 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). Для максимальной изоляции в функциональном стиле подходят замыкания.
Ответ 18+ 🔞
Ну вот, сидишь ты такой, пишешь на JavaScript, и вдруг — бац! — тебе понадобилось спрятать какие-то данные, чтобы не торчали, как хуй с горы, на всеобщее обозрение. А в языке-то, ёпта, такого 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, потому что поле приватное, иди нахуй
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). Если ты фанат функциональщины и хочешь полной изоляции — тебе в замыкания. Главное — не выставляй наружу то, что не нужно, а то будет тебе хиросима в коде.