Часто возникает ситуация при создании монолитного класса, когда необходимо внутри функции вызвать методы или свойства, главного класса. При этом область видимости удобного для этих целей 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() является незаменимой вещью при построении больших приложений методом пред настроенных классов.