Mootools. Ключевое слово this

  • Содержание

В JavaScript классы имеют свою область видимости переменных. Ключевое слово this позволит Вам отделить переменные, определенные внутри класса, от внешних - глобальных. В JavaScript this работает своеобразно, не так, как в других языках. В отличие от других языков значение this не привязывается статически ни к какому объекту, а зависит от контекста вызова. Разобраться в его поведении, определить, какое значение оно хранит, поможет эта статья.

Первый пример

// Переменная msg относится к глобальным переменным или к объекту window
// По сути, для обращения к переменной Вы можете вместо msg писать window.msg

var msg = 'я глобальная переменная';
 
// Создавая класс Bar, мы создаем локальное пространство внутри класса

var Bar = new Class(
{
	msg : 'я внутри класса', // Переменная принадлежит классу Bar
	initialize : function()
	{
		// Сообщение "внутри класса Bar: я внутри класса"
		// Префикс "this" определяет переменную msg внутри класса
		alert('внутри класса Bar: ' + this.msg);

		// Сообщение "внутри класса Bar: я глобальная переменная"
		// Переменная msg без префикса является глобальной
		alert('внутри класса Bar: ' + msg);
	}
});
 
var foo = new Bar();
alert('вне класса Bar: ' + msg); // Сообщение "вне класса Bar: я глобальная переменная"

var foo и this.foo

Если Вы объявляете переменную внутри класса с var, она будет видна только внутри данного метода. Переменная с this является свойством класса.

var msg = 'я глобальная переменная';	// глобальная переменная
var Bar = new Class(
{
	initialize : function()
	{
		this.msg = 'я принадлежу классу Bar';	// msg как свойство класса Bar

		var msg = 'я принадлежу методу initialize';	// msg как переменная внутри метода initialize  

		// Сообщение "я принадлежу методу initialize".
		// Если объявление msg отсутствует внутри этого метода, JS выдаст сообщение 'я глобальная переменная'
		alert(msg);

		alert(this.msg);	//Сообщение "я принадлежу классу Bar"
	}
});
var bar = new Bar(); 

Класс внутри класса

В этом случае ключевое слово this будет относится к вложенному классу. Рассмотрим пример.

var Bar = new Class(
{
	msg : 'я внутри класса',
	initialize : function()
	{
		var fx = new Fx.Slide('myElement',
		{
			onComplete: function()
			{
				// this относится к классу Fx.Slide, а не Bar.
				Поэтому если свойство msg отсутствует в Fx.Slide, JS выдаст сообщение "undefined"
				alert(this.msg);
			}
		}).hide().slideIn();
	}
});
var bar = new Bar();

Способы изменить область видимости переменных

Function.bind()

function myFunction()
{
	// При простом вызове функции this будет относится к window
	this.setStyle('color', 'red');
};
 
// При вызове с bind, this относится к параметру myElement, поэтому цвет изменится у элемента myElement
var myBoundFunction = myFunction.bind(myElement);


Применяя этот метод можно решить проблему в предыдущем примере с классом Fx.Slide:

onComplete: function()
{
	alert(this.msg);
}.bind(this)

.bind() - удобный инструмент для связи с классом родителем, однако при большой вложенности, код заметно усложняется:

var Bar = new Class(
{
	msg : 'я внутри класса',
	initialize : function()
	{
		var myRequest = new Request.HTML(
		{
			update: 'myElement',
			url : 'test.html',
			onSuccess : function()
			{

				var fx = new Fx.Slide('myElement',
				{
					onComplete : function()
					{
						alert(this.msg);
					}.bind(this) // Связываем метод onComplete() класса Fx.Slide с Request.HTML

				}).hide().slideIn();

			}.bind(this) // Связываем метод onSuccess() класса Request.HTML с Bar
		}).send();
	}
});
 
var bar = new Bar();

Кроме того, использование этого метода запрещает использовать this в иных случаях, кроме как в качестве ссылки на класс-родитель. Поэтому Вы можете использовать другой метод.

var that = this;

Вы всегда можете сохранить значение this в какой-либо переменной.

var Bar = new Class(
{
	msg : 'я внутри класса',
	initialize : function()
	{
		var that = this;
		var fx = new Fx.Slide('myElement',
		{
			onComplete : function()
			{
				// таким образом, that относится к классу Bar
				// this относится к классу Fx.Slide
				alert(that.msg); //Сообщение "я внутри класса"
				console.log(this.options); //опции Fx.Slide в firebug
			}
		}).hide().slideIn();
	}
});
 
var bar = new Bar();

Данный подход не ограничивает использование this и более удобен при большой вложенности классов.

Думаю, разобранные примеры пригодятся Вам в написании собственных классов.

Понравилась статья? Подпишись на RSS.

Советую почитать:

Правильный Mootools код
Очередной релиз Mootools - 1.2.4
Mootools. Оптимизация выборки
Изучаем MooTools. Шаг 7 - AJAX
Изучаем MooTools. Шаг 5 - Элементы DOM

Построение дерева в Mootools Очередной релиз Mootools - 1.2.4

Комментарии

  • Kirill написал 07 октября 2009 года

    Спасибо! полезная статья. очень помогла!

    Ответить
  • lazycommit написал 18 января 2011 года

    Да. Статья окончательно расставила всё на свои места. Спасибо )

    Ответить
  • Артем написал 03 мая 2011 года

    Спасибо, благодаря вам я наконец то понял суть "bind" !

    Ответить
  • faiwer написал 22 мая 2011 года

    Пардон, а какое отношение имеет this к области видимости? Bind использует apply, которая, в свою очередь, подменяет объект this в вызываемой функции. Область видимости при этом не изменяется.

    Ответить