Объекты в JS: реализация ссылок на себя в свойствах
Быстрый ответ
Геттеры идеально подходят для создания вычисляемых свойств в объектах, а фабричные функции – для методов, которые ссылаются на сам объект.
Геттеры для непосредственного взаимодействия со свойствами:
const obj = {
a: 1,
get doubleA() { return this.a * 2; } // Привет, я – obj, и я удвоил себя! 👋
};
console.log(obj.doubleA); // Результат: 2
Фабричные функции для создания методов с ссылками на сам объект:
const createObj = () => {
let self = { a: 1 };
self.multiplyA = (x) => self.a * x; // Зеркальце, скажи, все ли умножили на моё значение a?
return self;
};
let obj = createObj();
console.log(obj.multiplyA(2)); // Результат: 2
this
и self
позволяют объекту обратиться к своим собственным свойствам изнутри.
Глубже в тему: усиление самоссылок
Динамическое кэширование свойств через геттеры
Геттеры в ES6 ведут себя подобно волшебникам — они создают динамические объекты, умело кэшируя вычисляемые свойства.
const dynamicObj = {
a: 1,
b: 2,
get sum() { // Напоминание к себе: не забыть про солнечный свет.
const value = this.a + this.b;
Object.defineProperty(this, 'sum', { value });
return value;
}
};
console.log(dynamicObj.sum); // Первый вызов геттера, запоминаем результат.
console.log(dynamicObj.sum); // Второй вызов – получаем сохранённое значение.
Первый вызов sum
сохраняет результат, что предотвращает повторные вычисления при обращении к свойству.
Ссылка на самого себя через замыкание функции
Локальная область видимости функции — прекрасный инструмент для создания свойств объекта, ссылками на которые являются сами эти свойства.
function initializeObj() {
let obj = { a: 1 };
obj.b = function() { return this.a + 1; }; // Буква B утверждает, что она знает, как прибавить к A.
return obj;
}
const obj = initializeObj();
console.log(obj.b()); // Результат: 2. B выдает на гора математическую задачку.
Инициализация объектов "на лету"
Вы можете использовать конструкцию new function() { ... }
, чтобы создать и инициализировать объект со свойствами, которые ссылаются на сам объект, непосредственно в коде.
const obj = new function() {
this.a = 1;
this.double = () => this.a * 2; // Когда A говорит "удвоить", оно это имеет в виду на полном серьезе.
};
console.log(obj.double()); // Результат: 2
Визуализация
На примере эскиза дома легче понять концепцию самоссылающихся свойств в объектах:
Эскиз дома (🏠):
1. Основание: { основной материал: 'бетон' }
2. Стены: { материал: 'кирпич' }
3. Крыша: { стиль: 'мансардная' }
Неудачная попытка самоссылки:
4. Цвет фасада: { цвет: 'такой же, как у стен' } // 🚫 Мы не можем ссылаться на 'Стены' при инициализации!
Функциональный подход:
5. getHouseWithColor() {
let house = { foundation: 'бетон', walls: 'кирпич', roof: 'мансардная'};
house.color = { paint: house.walls }; // ✅ Теперь фасад может сослаться на 'Стены'
return house;
}
Основная заметка: Так же как нельзя принимать 'Стены' за основание при составлении плана, так же в JavaScript нельзя ссылаться на другие свойства во время создания объектного литерала. Но функции позволяют формировать объекты постепенно.
Продвинутое использование ссылок на собственные свойства
Временные свойства и функции для инициализации
Использование временных свойств или функций упрощает процесс инициализации объектов, которые можно затем удалить после того, как они выполнили свою функцию.
const complexObj = {
tempFactor: 2,
a: 1,
b: 2,
init() {
this.c = this.a * this.tempFactor; // Я — C, я в два раза мощнее, чем A!
delete this.tempFactor; // TempFactor ушел на покой
delete this.init; // Init также больше не нужен.
return this;
}
}.init();
console.log(complexObj); // Результат: { a: 1, b: 2, c: 2 }
Баланс между мощностью и производительностью
Особо сложные механизмы самоссылок могут приводить к уменьшению производительности в приложениях, где важна скорость и лёгкость.
Изменчивость на протяжении жизненного цикла
Разработчик может захотеть добавить или изменить некоторые свойства или методы объекта после его создания:
let mutableObj = { a: 1 };
mutableObj.b = mutableObj.a * 2; // B тихим голосом произнесла: "Я – в два раза больше, чем A"
console.log(mutableObj.b); // Результат: 2
Это позволяет вам добавлять свойства к объекту уже после его инициализации, не проводя сложных вычислений.
Полезные материалы
- Работа с объектами – JavaScript | MDN — Объекты в JavaScript: ваш путь к званию маэстро.
- Легкое объяснение "this" в JavaScript — Прозрачное и понятное разъяснение нюансов работы с
this
. - Ссылки на объект и их копирование — Мир копирования объектов и ссылок на них, волшебный и могучий, словно из мира Гарри Поттера.
- javascript – Ссылки на себя в объектных литералах/инициализаторах – Stack Overflow — Здесь собраны великие знания: дискуссия о самоссылках при инициализации на Stack Overflow.
- Создание объектов в JavaScript: шаблоны и лучшие практики — SitePoint — Знание шаблонов создания объектов и лучших практик сделают из вас настоящего ниндзя в этой области.
- Понимание области видимости и контекста в JavaScript | Ryan Morr — Войдите в мир областей видимости и контекста в JavaScript и почувствуйте блаженство вследствие новых знаний.
- Immediately Invoked Function Expression – Beau teaches JavaScript – YouTube — Видеоуроки о IIFE (немедленно вызываемые функции), для интерактивного обучения.