Что такое scope и createDelegate() в ExtJS

Часто возникает ситуация при создании монолитного класса, когда необходимо внутри функции вызвать методы или свойства, главного класса.  При этом область видимости удобного для этих целей this весьма ограничена. В ExtJS для такой задачи имеется очень удобное решение.

Предположим у нас есть класс object1:

1.var object1 = {
2.    property1 : 'Свойство 1',
3.    method1 : function() {
4.        alert(this.property1);
5.    }
6.}

При вызове object1.method1(); У нас выпадет alert с текстом: «Свойство 1».

Создадим другой класс, назовем его object2

1.var object2 = {
2.    property1 : 'Свойство object2',
3.}

Теперь попробуем выполнить следующий код: object1.method1.call(object2); У нас выпадет alert с текстом: «Свойство object2». Почему так получилось ? Мы указали функции при вызове «scope» объект, то есть объект, который функция присвоила this, как будто бы мы написали в теле функции this = object2; поэтому текущим у нас оказался объект object2, а не object1.

Когда у нас нет возможности вызывать метод call, это например, происходит при создании новой функции, в ExtJS есть специальный метод createDelegate, который так же принимает в качестве аргумента «scope» объект, в данном случае object2:

1.var newFunction = object1.method1.createDelegate(object2);

Теперь если мы вызовем нашу созданную функцию newFunction(); то мы также получим alert c текстом: «Свойство object2».

Иногда «scope» объект удобно указывать через свойство объекта. Допустим у нас есть метод в классе AjaxObject, представляющий из себя ajax запрос, и есть свойство класса property1:

01.var AjaxObject = {
02.    property1: 'Свойство 1',
03.    scope: this,
04.    sendAxaj: function() {
05.        Ext.Ajax.request({
06.            url: '/api.php/' ,
07.            method: 'GET',
08.            success: this.ajaxSuccess,
09.            params: post,
10.            scope: this
11.        });
12.    },
13.    ajaxSuccess: function(response) {
14.        alert(this.property1);
15.    }
16.}

Для того, чтобы мы могли каждый раз использовать методы и свойства главного класса AjaxObject, мы прописываем объектам свойство scope: this. Это в первом случае позволяет нам легко использовать метод обратившись через this.ajaxSuccess. А во втором случае, в callback функции использовать свойство главного класса AjaxObject this.property1.

Scope и createDelegate() является незаменимой вещью при построении больших приложений методом пред настроенных классов.