Когда вы пишете сложный jQuery/javascript, как вам управлять с помощью this
без переопределения переменных this
, которые были определены ранее? У вас есть эмпирическое правило или личное предпочтение для обозначения ваших переменных this
(по мере того, как вложенность становится глубже)?
Есть моменты, когда я хочу, чтобы переменные из более высокой области были доступны для вложенных функций/обратных вызовов, но иногда бывают случаи, когда я хочу иметь чистый сланец/область; есть ли хороший способ вызвать функции/обратные вызовы, не беспокоясь о переменных столкновениях? Если да, то какой метод вы используете?
Какой-то супер глупый тестовый код:
$(document).ready(function() {
console.warn('start');
var $this = $(this),
$dog = $('#dog'),
billy = function() {
console.log('BILLY!', 'THIS:', $this, ' | ', 'DOG:', $dog);
var $this = $(this);
console.log('BILLY!', 'THIS:', $this, ' | ', 'DOG:', $dog);
};
// (#1)
billy(); // BILLY! THIS: undefined | DOG: jQuery(p#dog)
// BILLY! THIS: jQuery(Window /demos/this/) | DOG: jQuery(p#dog)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: jQuery(Document /demos/this/) | DOG: jQuery(p#dog)
// (#2)
billy(); // BILLY! THIS: undefined | DOG: jQuery(p#dog)
// BILLY! THIS: jQuery(Window /demos/this/) | DOG: jQuery(p#dog)
$('#foo').slideUp(function() {
// (#3)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // BILLY! THIS: undefined | DOG: jQuery(p#dog)
var $this = $(this); // (#10)
// (#4)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // BILLY! THIS: jQuery(Window /demos/this/) | DOG: jQuery(p#dog)
});
$('#clickme').click(function() {
// (#5)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: undefined | DOG: jQuery(p#dog)
var $this = $(this);
// (#6)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: jQuery(button#clickme) | DOG: jQuery(p#dog)
$('#what').animate({
opacity : 0.25,
left : '+=50',
height : 'toggle'
}, 500, function() {
// (#7)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: undefined | DOG: jQuery(p#dog)
var $this = $(this);
// (#8)
console.log('THIS:', $this, ' | ', 'DOG:', $dog); // THIS: jQuery(div#what) | DOG: jQuery(p#dog)
});
});
// (#9)
billy(); // THIS: undefined | DOG: jQuery(p#dog)
// THIS: jQuery(div#foo) | DOG: jQuery(p#dog)
console.warn('finish');
});
Здесь можно найти полную демо-страницу (jsbin.com).
Примечание.. Как вы можете видеть, я "помечен" комментариями номерами (#XX) для удобства.
Наблюдение 1:
Маркер (# 1)
BILLY! THIS: undefined | DOG: jQuery(p#dog)
Риторический вопрос: Почему $this
undefined, но $dog
доступен?
Ответ: Поскольку var
внутри этой области переопределяет $this
; это просто, что я пытаюсь log $this
, прежде чем он будет определен в этой области.
Если я прокомментирую var $this = $(this);
, то маркер (# 1) возвращает:
BILLY! THIS: jQuery(Document index2.html) | DOG: jQuery(p#dog)
BILLY! THIS: jQuery(Document index2.html) | DOG: jQuery(p#dog)
То же самое относится к марке (# 2), (# 3), (# 4), (# 5), (# 6), (# 7) и (# 8).
Основываясь на этом наблюдении (и, пожалуйста, исправьте меня, если я ошибаюсь здесь) Я предполагаю, что могу положить var $this = $(this);
в нижней части функции, и текущая область будет знать, что я хочу использовать текущую scope $this
(хотя он еще не определен), а не родительский $this
(хотя он определен как IS).
ВОЗМОЖНОЕ РЕШЕНИЕ ДЛЯ ИЗБЕЖАНИЯ $this
КОНФЛИКТЫ:
Если вы хотите кэшировать $(this)
вне/внутри других закрытий/функций/обратных вызовов и избегать коллизий, тогда следует использовать разные метки переменных, например, такие как:
var $$ = $(this);
var $this2 = $(this);
var $t = $(this);
var $that = $(this);
Вопрос:
Является ли решение выше, как вы могли бы избежать столкновений $this
? Если нет, то какая у вас техника?
Наблюдение 2:
Маркер (# 9)
THIS: undefined | DOG: jQuery(p#dog)
... $this
имеет значение undefined по указанным выше причинам, но:
THIS: jQuery(div#foo) | DOG: jQuery(p#dog)
... $this
теперь $('#foo')
!
Вопрос (ы):
Почему именно это произошло?
Это потому, что $this
был переопределен с помощью маркера (# 10)?
(Хм, мне кажется, что мне нужно "сбор мусора в Google" в javascript).
Опять же, при написании сложного jquery/javascript, какой лучший способ избежать этого типа переменного столкновения?
Надеюсь, это не ужасные вопросы. Заранее благодарим за то, что нашли время, чтобы помочь мне.:)