20.08.2012, 14:56
|
|
Кандидат Javascript-наук
|
|
Регистрация: 19.08.2012
Сообщений: 100
|
|
таки опять вопрос про this
Пытаюсь понять эту тему, потому пишу обыкновенный jquery-слайдер, но чтобы в объекте был.
Вот какая ерунда выходит:
PromoBlock = {
options: {
animateDuration: 800,
animateEasing: 'swing',
autoslideDelay: 2000
},
SwitchTo: function(index){
var options = this.options
…
},
AutoSlide: function(){
var Switch2Next = this.SwitchTo
var autoslideTimer = setInterval(Switch2Next,this.options.autoslideDelay)
},
Init: function(){
…
this.AutoSlide()
}
}
PromoBlock.Init()
Из этого кода вырезано всё несущественное для вопроса.
Функция SwitchTo вызывается либо сама по себе, либо через setInterval, который, как известно, меняет контекст.
Соответственно, когда вызывается через setInterval, внутри неё var options = this.options не срабатывает, поскольку this == window.
Вот только я не понимаю, как правильно поступить, чтобы и в этом случае this был объект PromoBlock.
|
|
20.08.2012, 15:07
|
|
Студент
|
|
Регистрация: 30.04.2012
Сообщений: 1,113
|
|
так попробуйте
var t=this;
var autoslideTimer = setInterval(Switch2Next,t.options.autoslideDelay)
|
|
20.08.2012, 15:18
|
|
Кандидат Javascript-наук
|
|
Регистрация: 19.08.2012
Сообщений: 100
|
|
vadim5june, спасибо. Но именно длительность интервала совершенно нормально передаётся и так. Ошибка именно внутри функции SwitchTo. Именно внутри неё this указывает на объект PromoBlock, если функция вызывается сама по себе, и на window, если функция вызвана через setInterval.
Природа этого явления понятна: setInterval — метод глобального объекта window, и соответственно, он задаёт контекст выполнения функции.
Непонятно, как вызвать эту функцию через setInterval, чтобы её контекст был объект PromoBlock
|
|
20.08.2012, 15:24
|
|
Быдлокодер;)
|
|
Регистрация: 19.11.2010
Сообщений: 4,338
|
|
Вы можете использовать вызовы call/apply, для явного указания this функции, а также можете явно привязать один контекст к функции, с помощью метода bind (для древних браузеров придётся реализовать самому).
Информацию о всех этих методах найти в инете не проблема.
|
|
20.08.2012, 15:26
|
|
Студент
|
|
Регистрация: 30.04.2012
Сообщений: 1,113
|
|
а если так
var t=this;
var autoslideTimer = setInterval(function(){Switch2Next.call(t)},this.options.autoslideDelay)
|
|
20.08.2012, 15:47
|
|
Кандидат Javascript-наук
|
|
Регистрация: 19.08.2012
Сообщений: 100
|
|
про call/apply была первая мысль, но с ходу не получилось, первая попытка была именно такой: var autoslideTimer = setInterval(function(){Switch2Next.call(t)},this.o ptions.autoslideDelay). Это не сработало.
Вот такой вариант работает исправно:
var t = this
var Switch2Next = function(){ t.SwitchTo.call(t) }
var autoslideDelay = t.options.autoslideDelay
var autoslideTimer = setInterval(Switch2Next,autoslideDelay)
При этом даже строка var autoslideDelay = t.options.autoslideDelay не обязательна, она присутствует только для большей наглядности.
Всё ли правильно я делаю? Не покидает ощущение, что что-то не так, хотя работает в браузерах всё исправно.
|
|
20.08.2012, 15:50
|
|
junior
|
|
Регистрация: 29.11.2011
Сообщений: 3,924
|
|
LittlePony, мы же тебе уже сказали и даже показали
__________________
Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук
|
|
20.08.2012, 15:56
|
|
Студент
|
|
Регистрация: 30.04.2012
Сообщений: 1,113
|
|
это промежуточное Switch2Next не нужно
по идее вот так должен работать
var t=this;
var autoslideTimer = setInterval(function(){t.SwitchTo()},this.options.autoslideDelay)
|
|
20.08.2012, 16:06
|
|
Кандидат Javascript-наук
|
|
Регистрация: 19.08.2012
Сообщений: 100
|
|
Сообщение от vadim5june
|
это промежуточное Switch2Next не нужно
по идее вот так должен работать
var t=this;
var autoslideTimer = setInterval(function(){t.SwitchTo()},this.options.autoslideDelay)
|
Да, работает. И кажется я даже начинаю понимать, почему это работает, мой вариант выше работает, а первый вариант не работал. Большое спасибо!
Скажите, правильно ли я теперь понимаю?
Вариант:
var t=this;
var autoslideTimer = setInterval(function(){t.SwitchTo()},this.options.autoslideDelay)
Здесь в переменной t уже вполне определённый объект, который до применения setInterval был определён как this, который в тот момент однозначно указывал на сам объект PromoBlock(и будет на него указывать, как его ни обозвать), у этого объекта есть метод SwitchTo, который и вызывается в контексте объекта, который из t уже никуда не денется, как бы setInterval ни менял контекст.
Вариант же мой рабочий — это почти то же самое, но расписанное большим количеством шагов.
|
|
20.08.2012, 16:08
|
|
Студент
|
|
Регистрация: 30.04.2012
Сообщений: 1,113
|
|
Сообщение от LittlePony
|
Здесь в переменной t уже вполне определённый объект, который до применения setInterval был определён как this, который в тот момент однозначно указывал на сам объект PromoBlock(и будет на него указывать, как его ни обозвать), у этого объекта есть метод SwitchTo, который и вызывается в контексте объекта, который из t уже никуда не денется, как бы setInterval ни менял контекст
|
да правильно вызываем метод объекта PromoBlock
|
|
|
|