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

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

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

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

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

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

var object2 = {
    property1 : 'Свойство object2',
}

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

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

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

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

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

var AjaxObject = {
    property1: 'Свойство 1',
    scope: this,
    sendAxaj: function() {
        Ext.Ajax.request({
            url: '/api.php/' ,
            method: 'GET',
            success: this.ajaxSuccess,
            params: post,
            scope: this
        });
    },
    ajaxSuccess: function(response) {
        alert(this.property1);
    }
}

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

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