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