Symbol: как добавлять внутренние свойства объектов без конфликтов!
В JavaScript объекты часто используются разными частями приложения, библиотеками и компонентами одновременно. Иногда требуется добавить к существующему объекту дополнительные данные: состояние компонента, метаданные, кэш или внутренние флаги.
Добавление обычных свойств может привести к конфликтам. Если такое имя уже используется другим кодом, одно значение может случайно заменить другое.
const element = {
value: "button"
};
element.state = {
mounted: true
};
Если свойство
Для решения этой задачи существует
const internalState = Symbol("internalState");
const component = {
value: "button",
[internalState]: {
mounted: true
}
};
console.log(component[internalState]);
// { mounted: true }
Теперь внутренние данные хранятся по уникальному ключу. Объект можно расширять дополнительным состоянием, не изменяя его публичную структуру.
Даже если другой код добавит свойство с похожим названием, конфликт не возникнет:
component.internalState = false;
console.log(component[internalState]);
// { mounted: true }
Symbol-свойства имеют ещё одну особенность: они не отображаются в большинстве стандартных способов перебора объектов. Например,
Object.keys(component);
// ["value"]
Это позволяет хранить дополнительные данные внутри объекта, не добавляя их в обычное представление объекта и его публичный API. При необходимости получить символьные свойства можно явно:
Object.getOwnPropertySymbols(component);
Такой подход часто используется в библиотеках и компонентах, которым необходимо хранить внутренние данные, связанные с объектом. Например, можно добавить метаданные компонента:
const meta = Symbol("meta");
function initComponent(component) {
component[meta] = {
id: crypto.randomUUID(),
createdAt: Date.now()
};
}
После этого объект получает внутреннюю информацию, но его внешний интерфейс остаётся неизменным:
component.id;
// undefined
component[meta].id;
// UUID
Кроме пользовательских символов, JavaScript содержит встроенные
Symbol.iterator
Symbol.asyncIterator
Symbol.toPrimitive
Например,
const collection = {
items: ["a", "b"],
[Symbol.iterator]() {
return this.items[Symbol.iterator]();
}
};
for (const item of collection) {
console.log(item);
}
Важно понимать:
Object.getOwnPropertySymbols();
Reflect.ownKeys();
Основная задача
🔥
📣 Code Ready | #практика
В JavaScript объекты часто используются разными частями приложения, библиотеками и компонентами одновременно. Иногда требуется добавить к существующему объекту дополнительные данные: состояние компонента, метаданные, кэш или внутренние флаги.
Добавление обычных свойств может привести к конфликтам. Если такое имя уже используется другим кодом, одно значение может случайно заменить другое.
const element = {
value: "button"
};
element.state = {
mounted: true
};
Если свойство
state уже существует в объекте, новое значение перезапишет старое. В больших приложениях такие ситуации могут быть сложными для поиска, особенно когда объект расширяется несколькими независимыми модулями.Для решения этой задачи существует
Symbol — это примитивный тип данных, который создаёт уникальные ключи свойств объектов. Каждый созданный символ является уникальным, поэтому он не может случайно совпасть с обычным строковым свойством или другим символом.const internalState = Symbol("internalState");
const component = {
value: "button",
[internalState]: {
mounted: true
}
};
console.log(component[internalState]);
// { mounted: true }
Теперь внутренние данные хранятся по уникальному ключу. Объект можно расширять дополнительным состоянием, не изменяя его публичную структуру.
Даже если другой код добавит свойство с похожим названием, конфликт не возникнет:
component.internalState = false;
console.log(component[internalState]);
// { mounted: true }
Symbol-свойства имеют ещё одну особенность: они не отображаются в большинстве стандартных способов перебора объектов. Например,
Object.keys() возвращает только строковые ключи:Object.keys(component);
// ["value"]
Это позволяет хранить дополнительные данные внутри объекта, не добавляя их в обычное представление объекта и его публичный API. При необходимости получить символьные свойства можно явно:
Object.getOwnPropertySymbols(component);
Такой подход часто используется в библиотеках и компонентах, которым необходимо хранить внутренние данные, связанные с объектом. Например, можно добавить метаданные компонента:
const meta = Symbol("meta");
function initComponent(component) {
component[meta] = {
id: crypto.randomUUID(),
createdAt: Date.now()
};
}
После этого объект получает внутреннюю информацию, но его внешний интерфейс остаётся неизменным:
component.id;
// undefined
component[meta].id;
// UUID
Кроме пользовательских символов, JavaScript содержит встроенные
Symbol, которые позволяют изменять стандартное поведение объектов:Symbol.iterator
Symbol.asyncIterator
Symbol.toPrimitive
Например,
Symbol.iterator позволяет объекту поддерживать цикл for...of:const collection = {
items: ["a", "b"],
[Symbol.iterator]() {
return this.items[Symbol.iterator]();
}
};
for (const item of collection) {
console.log(item);
}
Важно понимать:
Symbol не является механизмом настоящей приватности. Символьные свойства можно найти через:Object.getOwnPropertySymbols();
Reflect.ownKeys();
Основная задача
Symbol — создавать уникальные ключи и безопасно расширять объекты без риска конфликтов имён. Для настоящей приватности в классах JavaScript используются #private fields.🔥
Symbol — практический инструмент для создания библиотек, компонентов и больших frontend-систем, где требуется добавлять внутренние данные, сохраняя чистый публичный API объекта.📣 Code Ready | #практика
Издательский дом «Новые отраслевые медиа» собрал для вас лучшие каналы из сферы искусственного интеллекта и интернет-технологий, которые помогают своим подписчикам быть в курсе всех важных профессиональных новостей.
Здесь - всё про ключевых игроков отрасли, государственное регулирование, инсайды и кейсы от отраслевых лидеров.
✅Серверная - канал об индустрии дата-центров: технологиях, инфраструктуре, облачных решениях, энергоэффективности и применении ЦОД в ключевых отраслях экономики.
✅Робосфера - канал об индустрии робототехники: технологии и тренды. Промышленные и сервисные роботы, коботы, автоматизация, ИИ, машинное зрение, автономные системы.
✅AI для бизнеса - всё об AI-решениях для бизнеса: внедрение, автоматизация, корпоративный ИИ, агенты.
✅ТехноРитейл - канал о производстве и продаже бытовой техники и электроники в России: бренды, e-com, маркетинг, retail tech.
Подписывайтесь, и эти каналы смогут изменить вашу жизнь к лучшему!
Реклама. Харламов А.Е. ИНН 712803816807. erid: 2W5zFJNTBaZ
Здесь - всё про ключевых игроков отрасли, государственное регулирование, инсайды и кейсы от отраслевых лидеров.
✅Серверная - канал об индустрии дата-центров: технологиях, инфраструктуре, облачных решениях, энергоэффективности и применении ЦОД в ключевых отраслях экономики.
✅Робосфера - канал об индустрии робототехники: технологии и тренды. Промышленные и сервисные роботы, коботы, автоматизация, ИИ, машинное зрение, автономные системы.
✅AI для бизнеса - всё об AI-решениях для бизнеса: внедрение, автоматизация, корпоративный ИИ, агенты.
✅ТехноРитейл - канал о производстве и продаже бытовой техники и электроники в России: бренды, e-com, маркетинг, retail tech.
Подписывайтесь, и эти каналы смогут изменить вашу жизнь к лучшему!
Реклама. Харламов А.Е. ИНН 712803816807. erid: 2W5zFJNTBaZ
Telegram
Серверная | ЦОД, облака
Канал об индустрии дата-центров: технологиях, инфраструктуре, облачных решениях, энергоэффективности и применении ЦОД в ключевых отраслях экономики
ИД НОМ idnom.ru
Связь с редакцией и по вопросам рекламы @id_nom
ИД НОМ idnom.ru
Связь с редакцией и по вопросам рекламы @id_nom
💾 Deconstructed Cards – два варианта карточек с эффектом зума и подвижным фоном. Текст в активном режиме становится ярче, а графика – заметнее.
Сайтодел | #сниппет #css
Сайтодел | #сниппет #css
💾 Text Circle Animation – круг со словами, который можно вращать курсором. При быстром движении буквы "разлетаются" в стороны.
Сайтодел | #сниппет #css
Сайтодел | #сниппет #css
HTMLImageElement.decode() — подготовка изображения до появления в DOM!
При динамической подстановке изображений часто возникает ситуация, когда элемент уже добавлен в DOM, но браузер ещё не завершил декодирование изображения. В результате пользователь может увидеть пустую область, задержку появления контента или заметное изменение содержимого после завершения подготовки картинки.
Для таких случаев существует метод
const image = new Image();
image.src = '/images/photo.jpg';
await image.decode();
После установки
После успешного выполнения
const image = new Image();
image.src = '/images/photo.jpg';
await image.decode();
document.body.append(image);
В таком случае браузеру не требуется выполнять декодирование в момент первого отображения элемента, что помогает избежать визуальных скачков при динамическом обновлении интерфейса.
Метод особенно полезен при динамической замене изображений:
const preview = document.querySelector('.preview');
const nextImage = new Image();
nextImage.src = '/images/next.jpg';
await nextImage.decode();
preview.replaceWith(nextImage);
Новая картинка будет установлена только после подготовки браузером, поэтому замена происходит без промежуточного состояния, связанного с декодированием изображения.
Важно учитывать разницу между загрузкой и декодированием. Событие
image.onload = () => {
console.log('Изображение загружено');
};
await image.decode();
Эти механизмы решают разные задачи и могут использоваться вместе в зависимости от требований интерфейса.
При ошибке загрузки или невозможности декодировать изображение
try {
await image.decode();
} catch (error) {
console.error('Не удалось подготовить изображение', error);
}
Важно учитывать, что
<img src="/images/photo.jpg" width="800" height="600">
🔥
📣 Code Ready | #практика
При динамической подстановке изображений часто возникает ситуация, когда элемент уже добавлен в DOM, но браузер ещё не завершил декодирование изображения. В результате пользователь может увидеть пустую область, задержку появления контента или заметное изменение содержимого после завершения подготовки картинки.
Для таких случаев существует метод
decode(), который позволяет дождаться момента, когда изображение будет декодировано браузером и готово к безопасному отображению. Создадим объект изображения:const image = new Image();
image.src = '/images/photo.jpg';
await image.decode();
После установки
src браузер начинает загрузку ресурса. Метод decode() не является механизмом загрузки изображения — он ожидает завершения загрузки и последующего декодирования, чтобы браузер не выполнял эту работу непосредственно в момент первого отображения.После успешного выполнения
Promise изображение можно добавлять в DOM:const image = new Image();
image.src = '/images/photo.jpg';
await image.decode();
document.body.append(image);
В таком случае браузеру не требуется выполнять декодирование в момент первого отображения элемента, что помогает избежать визуальных скачков при динамическом обновлении интерфейса.
Метод особенно полезен при динамической замене изображений:
const preview = document.querySelector('.preview');
const nextImage = new Image();
nextImage.src = '/images/next.jpg';
await nextImage.decode();
preview.replaceWith(nextImage);
Новая картинка будет установлена только после подготовки браузером, поэтому замена происходит без промежуточного состояния, связанного с декодированием изображения.
Важно учитывать разницу между загрузкой и декодированием. Событие
load сообщает о завершении загрузки ресурса, а decode() отвечает за готовность изображения к отображению без дополнительной подготовки в момент рендера. Например:image.onload = () => {
console.log('Изображение загружено');
};
await image.decode();
Эти механизмы решают разные задачи и могут использоваться вместе в зависимости от требований интерфейса.
При ошибке загрузки или невозможности декодировать изображение
Promise будет отклонён:try {
await image.decode();
} catch (error) {
console.error('Не удалось подготовить изображение', error);
}
Важно учитывать, что
decode() не решает проблему layout shift (CLS), если размеры изображения заранее неизвестны. Для предотвращения скачков интерфейса рекомендуется задавать размеры через width / height или использовать aspect-ratio. Например:<img src="/images/photo.jpg" width="800" height="600">
decode() широко применяется в современных веб-интерфейсах: галереях, слайдерах, редакторах изображений и компонентах с динамическим обновлением контента, где важно контролировать момент появления изображения.🔥
HTMLImageElement.decode() позволяет синхронизировать отображение изображения с процессом его подготовки браузером и избежать визуальных артефактов при динамическом обновлении DOM.📣 Code Ready | #практика
Дедлайны горят, а твои глаза уже нет. Что делать, если ты за#бался и хочется просто залипать в телефоне?
И вроде понимаешь, что НАДО, но от этого еще больше сопротивление.
Если близкие думают, что ты зажрался, а тебе и самому от себя уже тошно, но как себя взбодрить – непонятно, советую посмотреть вот что: https://t.me/Manifestans
Ты 100% себя узнаешь, а значит 100% получишь пользу от того, что там увидишь!
Если ты еще не собрал пожитки и не ушел отшельником в лес – есть шанс тебя оживить и вернуть эмоции и интерес к жизни.
Кликай сюда и начинай приходить в себя.
И вроде понимаешь, что НАДО, но от этого еще больше сопротивление.
Если близкие думают, что ты зажрался, а тебе и самому от себя уже тошно, но как себя взбодрить – непонятно, советую посмотреть вот что: https://t.me/Manifestans
Ты 100% себя узнаешь, а значит 100% получишь пользу от того, что там увидишь!
Если ты еще не собрал пожитки и не ушел отшельником в лес – есть шанс тебя оживить и вернуть эмоции и интерес к жизни.
Кликай сюда и начинай приходить в себя.
Добавляем дополнительную информацию с помощью тега <small>!
Тег
Для чего <small> подойдёт идеально:
• пояснения;
• комментарии;
• дисклеймеры;
• предостережения;
• копирайт;
• информация о лицензии;
• прочая правовая информация.
Важно:
📣 Code Ready | #атрибут
Тег
<small> используется для отображения второстепенного текста, который имеет меньшее значение по сравнению с основным содержимым. Он подходит для информации, которая полезна пользователю, но не является частью основного сообщения.Для чего <small> подойдёт идеально:
• пояснения;
• комментарии;
• дисклеймеры;
• предостережения;
• копирайт;
• информация о лицензии;
• прочая правовая информация.
Важно:
<small> имеет семантическое значение, а не просто уменьшает размер текста. Для изменения визуального размера обычного текста лучше использовать CSS.📣 Code Ready | #атрибут
💾 Services Section – карточки с выдвигающимся фоном и композицией из четырех картинок-сегментов. В активном состоянии цвет текста становится ярче.
Сайтодел | #сниппет #css
Сайтодел | #сниппет #css
🖥 Health Analytics App – дизайн для мобильного приложения с аналитикой здоровья. Основные черты – выдержанный стиль, насыщенные холодные тона, контрасты и отсутствие скругленных углов.
Сайтодел | #макет #figma
Сайтодел | #макет #figma
💀 Пароль, который удаляет всё содержимое смартфона
В США впервые возбудили уголовное дело из-за функции самоуничтожения смартфона.
Чувак вместо пароля назвал агентам специальный код GrapheneOS — телефон мгновенно стер все данные вместе с eSIM, оставив силовиков ни с чем.
Теперь мужчину обвиняют в уничтожении доказательств и воспрепятствовании законному изъятию имущества. Максимальное наказание — до 5 лет тюрьмы.
При этом защита утверждает, что ордера на обыск не было, а просьбы вызвать адвоката проигнорировали.
Стартаперы, ловите идею для приложения 😎
В США впервые возбудили уголовное дело из-за функции самоуничтожения смартфона.
Чувак вместо пароля назвал агентам специальный код GrapheneOS — телефон мгновенно стер все данные вместе с eSIM, оставив силовиков ни с чем.
Теперь мужчину обвиняют в уничтожении доказательств и воспрепятствовании законному изъятию имущества. Максимальное наказание — до 5 лет тюрьмы.
При этом защита утверждает, что ордера на обыск не было, а просьбы вызвать адвоката проигнорировали.
Стартаперы, ловите идею для приложения 😎
RSS дайджест за 31 июля готов и сохранён в
🤖 RSS Дайджест — 31 июля 2026
───
🤖 AI/LLM
• Anthropic: ИИ-модели взломали 3 компании — во время security tests
• Minimax-H3: видеомодель вышла, open weights скоро
• LG AI Research: K-EXAONE 2.0 750B — корейская модель
• Inkling-Small-276B-12B — новая модель от thinkingmachines
• Бенчмарки не работают?
🤖 Robotics
• Gemini Robotics 2 — Google DeepMind
🛠 Tech
• Stacked PRs теперь в GitHub
• Google: AI исправила в Chrome больше багов за июнь, чем за 2 года
• Krebs: Don't buy that TV streaming stick
🍎 Apple
• Apple: значительные supply constraints
• Gaming slowdown и App Store ударили по services
• Reddit: solid quarter, но AI давит
───
Источники: TechCrunch, HN, r/LocalLLaMA
data/digest-2026-07-31.md.🤖 RSS Дайджест — 31 июля 2026
───
🤖 AI/LLM
• Anthropic: ИИ-модели взломали 3 компании — во время security tests
• Minimax-H3: видеомодель вышла, open weights скоро
• LG AI Research: K-EXAONE 2.0 750B — корейская модель
• Inkling-Small-276B-12B — новая модель от thinkingmachines
• Бенчмарки не работают?
🤖 Robotics
• Gemini Robotics 2 — Google DeepMind
🛠 Tech
• Stacked PRs теперь в GitHub
• Google: AI исправила в Chrome больше багов за июнь, чем за 2 года
• Krebs: Don't buy that TV streaming stick
🍎 Apple
• Apple: значительные supply constraints
• Gaming slowdown и App Store ударили по services
• Reddit: solid quarter, но AI давит
───
Источники: TechCrunch, HN, r/LocalLLaMA
💾 CSS Single Element Goey Spinner – лоадер из "жидких" капель, которые перетекают друг в друга по направлению движения. Лучше всего будет выглядеть на белом фоне.
Сайтодел | #сниппет #css
Сайтодел | #сниппет #css
🎨 Цветовая палитра макета "Restaurant Reversion App"
⚠️ Цвет копируется одним кликом!
Сайтодел | #палитра
HEX | RGB #EDEDE5 | rgb(237, 237, 229)#F27BF1 | rgb(242, 123, 241)#8D8CF4 | rgb(141, 140, 244)⚠️ Цвет копируется одним кликом!
Сайтодел | #палитра