Манипулирование контекстом объекта

Глобальный объект window обеспечивает в вебприложениях самый внешний уровень контекста, но иногда бывает необходимо изменить контекст по умолчанию на какойто другой. Например, у вас может возникнуть потребность сохранять состояние сеанса, когда пользователь завершает работу с приложением. Или у вас, может быть, какая то особенная среда выполнения, которая уже настроена под определенные обстоятельства. Тогда вместо того чтобы каждый раз заставлять программный код выполнять проверку всех условий для настройки среды, вы могли бы средствами библиотеки Base поменять один существующий контекст на другой.

Следующая функция позволяет изменять объект dojo.global и dojo.doc по своему усмотрению. Обратите внимание: по умолчанию dojo.doc – это простая ссылка на window.document, но несмотря на это, она обеспечивает единообразный способ идентификации контекста текущего документа, что опять же может быть весьма удобно в ситуациях, когда вопрос касается управления контекстами объектов. Функция dojo.body() –
это сокращенный способ получить ссылку на тело документа.

Вам необходимо знать о существовании как минимум трех функций из библиотеки Base, чтобы успешно управлять контекстом:
dojo.doc //Возвращает Document
dojo.body() //Возвращает DomNode
dojo.setContext(/*Object*/globalObject, /*Document*/globalDocument)

Наконец, для большей гибкости библиотека Base предоставляет две функции, позволяющие вызывать функцию либо в контексте другого окружения dojo.global, либо в контексте другого документа dojo.doc,
отличных от текущих.
dojo.withGlobal(/*Object*/globalObject, /*Function*/callback,
/*Object*/thisObject, /*Array*/callbackArgs)
dojo.withDoc(/*Object*/documentObject, /*Function*/callback,
/*Object*/thisObject, /*Array*/callbackArgs)

Следует заметить, что применение функций Dojo для активной работы в другом объекте document или window еще не достаточно хорошо проверено, поэтому вы можете столкнуться с некоторыми проблемами, если пойдете этим путем.


Стандартное использование предполагает загрузку инструментария Dojo в каждый документ, где он, как планируется, будет использоваться. Однако, в случае выполнения несложных операций обсуждаемые здесь функции управления контекстом работают замечательно.

Передача параметров по частям
Функция partial из библиотеки Base позволяет передавать параметры функции частями по мере их готовности и производить фактический вызов функции позднее. Или можно определить значения всех параметров сразу и передать ссылку на функцию, которую можно будет вызвать позднее. Этот прием выглядит проще, чем передача функции вместе с параметрами, и широко используется по всему инструментальному набору. Ниже приводится сигнатура функции partial:
dojo.partial(*/Function|String*/func /*, arg1, ..., argN*/) //Возвращает Any

Для иллюстрации ниже приводится простой пример использования функции partial для передачи параметров функции, вычисляющей сумму последовательности чисел:
function addThree(x,y,z) { console.log(x+y+z);}
//передать два первых аргумента
f = dojo.partial(addThree, 100, 10);
//передать последний аргумент
f = dojo.partial(f, 1);
//а теперь вызвать функцию
f(); //111

Связывание объекта с определенным контекстом
Функция hitch из библиотеки Base очень напоминает функцию par-tial, – в том смысле, что тоже позволяет передавать параметры частями.


Но у нее есть одна интересная особенность, которая заключается в том, что она позволяет связывать функцию с определенным контекстом выполнения, который будет установлен независимо от того, в каком контексте будет произведен вызов функции. Это может быть особенно удобно в ситуациях, когда имеется функция обратного вызова, и заранее никогда точно не известно, каков будет контекст (то есть значение ссылки this) при вызове функции. Сигнатура функции hitch имеет следующий вид:
dojo.hitch(/*Object*/scope, /*Function||String*/method /*, arg1, ... , argN*/)
//Возвращает Any

А для иллюстрации ниже приводится простой пример, где переопределяется контекст метода объекта:
var foo = {
name : "Foo",
greet : function() {
console.log("Hi, I'm", this.name);
}
}
var bar = {
name : "Bar",
greet : function() {
console.log("Hi, I'm", this.name);
}
}
foo.greet(); //Hi, I'm Foo
bar.greet(); //Hi, I'm Bar
/* Связать метод greet объекта bar с другим контекстом */
bar.greet = dojo.hitch(foo, "greet");
/ * Теперь объект bar будет выдавать себя за другой объект */
bar.greet(); // Hi, I'm Foo

Дополню: поскольку функция greet явно ссылается на контекст с помощью ссылки this, следующий фрагмент программного кода не переопределяет контекст метода greet:
bar.greet = foo.greet;
bar.greet();

Делегирование и наследование
Делегирование – это шаблон программирования, когда при выполнении действия один объект опирается на другой объект, а не предусматривает собственную реализацию этого действия.


Делегирование – это самое сердце JavaScript как языка, основанного на прототипах, потому что делегирование – это именно тот прием, благодаря которому отыскиваются свойства объекта в цепочке прототипов. Несмотря на то, что делегирование составляет самую основу реализации наследования в JavaScript, которая опирается на поиск в цепочке прототипов во время выполнения, тем не менее делегирование по своей сути совершенно отличается от наследования в настоящих объектноориентированных языках программирования, таких как Java и C++, в которых часто (но далеко не всегда) разрешение имен в иерархии классов выполняется на этапе компиляции, а не во время выполнения. В этом смысле особенно примечательно, что, будучи особенностью времени выполнения, делегирование в обязательном порядке опирается на механизм динамического связывания как на особенность языка.

Функция delegate инструментального набора Dojo реализует механизм делегирования функции объекта и имеет следующую сигнатуру:
dojo.delegate(/*Object*/delegate, properties) //Возвращает Object

Основываясь на предыдущем примере, следующий отрывок демонстрирует, как можно с помощью делегирования получить объект, который делегирует вызов функции другому объекту:
function Foo() {
this.talk = function() {console.log("Hello, my name is", this.name);}
}
// Получить объект типа Function, имеющий свойство name,
// но передает или делегирует обязательство вызова функции talk
// экземпляру Foo, который передается функции delegate.
var bar = dojo.delegate(new Foo, {name : "Bar"});
// Вызывается метод делегата Foo
bar.talk();

Оцените статью: (0 голосов)
0 5 0

Статьи из раздела Dojo на эту тему:
Аргументы «функции в виде строк»
Блочная модель
Грубое определение типа
Добавление узлов
Зачем управлять беспорядком

Вернуться в раздел: Dojo / Утилиты броузера