Я стараюсь следовать совету Дугласа Крокфорда из "JavaScript: Хорошие части" и его веб-сайта:
Использование глобальных переменных должно быть сведено к минимуму.Подразумеваемые глобальные переменные никогда не должны использоваться.
Для этого я определил один «корневой» объект, который действует как контейнер для всех других объектов, и теперь все организовано в логическую иерархию общихфункциональность.
Где я озадачен, так это то, как дочерние объекты, похоже, теряют область видимости глобального объекта.Лучший пример, который я могу привести здесь, - это мой регистратор, который я хочу определить глобально как root.log и использовать его повсюду.
Однако, когда япопробуйте получить доступ к root.log внутри дочернего объекта, мой код завершается ошибкой, потому что он не видит никакой ссылки на объект root Больше.Я перемещаю дочерний объект в глобальную область видимости, и он снова видит все нормально.
Я видел другие публикации в переполнении стека, которые предоставляют решения для связи родительского / дочернего объекта путем явной передачи родительской ссылки в дочерний объект, но это не то, что я здесь после.Я хочу иметь доступ к корню из любой точки, и если я на три или четыре уровня ниже, мне не нужно иметь дело с отслеживанием обратной цепочки.
Явный пример этого можетбыть, если я в глубине своей служебной иерархии, и я хочу записать сообщение.Допустим, я нахожусь на root.util.array.getPositionInArray () , и я передал родительское значение в каждый подобъект.Я не хочу вызывать parent.parent.parent.log.write , я просто хочу сделать один простой вызов root.log.напишите .
Я мог бы передать ссылки на корневой и родительский объекты в каждый подобъект по мере их создания, или, возможно, поэкспериментировать с некоторыми принципами наследования и посмотреть, смогу ли я заставить его работать таким образом.
У меня следующие вопросы:
Почему глобальная область действия "исчезает", когда я нахожусь в объекте, определенном внутри другого объекта?
Есть ли простой способ получить доступ к этой глобальной переменной изнутри подобъектов?
(возможно, дубликат 2). Каков рекомендуемый способ справиться с этим?
Мой пример кода приведен ниже (здесь он загружен в jsfiddle )
// declare root object as global variable
var root = null;
$(document).ready(function() {
// instantiate root
root = new Foo();
// uncomment to instantiate child separately
// child = new ChildFoo();
// write to log from outside parent (shows scope is global)
root.log.write(root.x)
root.log.write(root.child.x);
});
function Foo() {
// instantiate logger as child of parent
this.log = new Logger("output");
// write a quick message
this.log.write("Foo constructor");
// set value of x
this.x = 1;
// instantiate child object
this.child = new ChildFoo;
}
// child object definition
function ChildFoo() {
// why is root.log == null here?
root.log.write("Child constructor");
// this reference to parent also fails
// this.x = 10 * root.x;
this.x = 10;
}
// log object definition
function Logger(container) {
// store reference to dom container
this.container = container;
}
// method to write message to dom
Logger.prototype.write = function(message) {
$("#" + this.container).append("[" + new Date() + "] " + message + "<br>");
}
Мне удалось заставить это работатьдобавив следующий раздел в начало определения объекта Foo.Это немедленно предоставляет ссылку на глобальный объект корневому объекту, а также реализует шаблон Singleton, чтобы гарантировать наличие только одного корневого объекта.Jsfiddle был полностью обновлен с этим.
if(root != null){
root.log.write("Root object already instantiated");
return root;
} else {
root = this;
}