Контекст выполнения (execution context) в JavaScript определяет,
в каком окружении вызывается функция и к чему
привязано ключевое слово this. В библиотеке mo.js
этот механизм играет важную роль, поскольку многие анимации создаются
через методы объектов и классов, где корректная привязка контекста
влияет на поведение анимации.
Контекст выполнения формируется в момент вызова функции и включает:
thisthis в
разных сценарияхКонтекст функции определяется способом её вызова.
1. Обычный вызов функции
function test() {
console.log(this);
}
test(); // window (или undefined в strict mode)
2. Вызов как метода объекта
const obj = {
value: 42,
show() {
console.log(this.value);
}
};
obj.show(); // 42
3. Вызов через конструктор
function Item() {
this.name = 'circle';
}
const item = new Item();
4. Явная привязка (call, apply,
bind)
function show() {
console.log(this.name);
}
const obj = { name: 'mojs' };
show.call(obj); // mojs
В библиотеке mo.js контекст часто используется внутри:
Пример создания анимации:
const circle = new mojs.Shape({
shape: 'circle',
radius: 50,
fill: 'red'
});
Здесь контекст важен при использовании функций внутри параметров.
При передаче функции как аргумента контекст может быть утерян.
const obj = {
radius: 50,
animate() {
setTimeout(function () {
console.log(this.radius);
}, 1000);
}
};
obj.animate(); // undefined
Причина — функция внутри setTimeout вызывается отдельно,
без привязки к obj.
Стрелочные функции не имеют собственного
this, а наследуют его из внешнего контекста.
const obj = {
radius: 50,
animate() {
setTimeout(() => {
console.log(this.radius);
}, 1000);
}
};
obj.animate(); // 50
Это часто используется в mo.js при описании анимаций и событий.
bindДругой способ — явная привязка контекста.
const obj = {
radius: 50,
animate() {
setTimeout(function () {
console.log(this.radius);
}.bind(this), 1000);
}
};
При создании кастомных эффектов:
const burst = new mojs.Burst({
count: 5,
children: {
shape: 'circle',
fill: 'blue',
delay: function(index) {
return index * 100;
}
}
});
Здесь функция delay получает параметры
(index), но контекст (this) не
привязан к экземпляру.
Если требуется доступ к внешнему объекту, используется замыкание:
const baseDelay = 50;
const burst = new mojs.Burst({
children: {
delay: function(index) {
return baseDelay + index * 100;
}
}
});
При работе с классами:
class Animator {
constructor() {
this.shape = new mojs.Shape({ radius: 20 });
}
start() {
this.shape.play();
}
}
Контекст метода start зависит от способа вызова:
const anim = new Animator();
const start = anim.start;
start(); // ошибка: this = undefined
Методы теряют контекст при передаче:
button.addEventListener('click', anim.start);
Решение:
button.addEventListener('click', anim.start.bind(anim));
или:
button.addEventListener('click', () => anim.start());
mo.js позволяет работать с timeline и событиями:
const timeline = new mojs.Timeline();
timeline.add(circle);
timeline.play();
При добавлении пользовательской логики:
timeline.add({
onComplete: function() {
console.log(this);
}
});
Контекст может не указывать на ожидаемый объект, поэтому чаще применяются стрелочные функции:
timeline.add({
onComplete: () => {
console.log('анимация завершена');
}
});
Контекст тесно связан с замыканиями — функциями, сохраняющими доступ к внешним переменным.
function createAnimator(speed) {
return function() {
console.log(speed);
};
}
const anim = createAnimator(300);
anim(); // 300
В mo.js это полезно для:
В строгом режиме:
'use strict';
function test() {
console.log(this);
}
test(); // undefined
Это важно учитывать при разработке сложных анимаций, чтобы избежать
неожиданных значений this.
Использование стрелочных функций:
Использование bind:
Избегание неявного контекста:
this в функциях, передаваемых как
аргументы1. Потеря контекста
const fn = obj.method;
fn(); // this потерян
2. Неправильное использование стрелочных функций
const obj = {
value: 10,
method: () => {
console.log(this.value);
}
};
obj.method(); // undefined
3. Ожидание контекста внутри callback mo.js
delay: function() {
console.log(this); // не то, что ожидается
}
В mo.js правильное управление контекстом позволяет:
Контекст становится ключевым элементом при переходе от простых анимаций к архитектурно сложным системам с использованием таймлайнов, классов и пользовательских эффектов.