Возможно ли передать контекст выполнения сразу вызываемого выражения функции
Рассмотрим следующий код:
(function() {
var a = 5;
var someFunc = function() { ... };
function anotherFunc() {
...
};
})();
window.myGlobalObj = {
init: function() {
// and somehow here I want to access to the IIFE context
}
};
Я хочу иметь контекст выполнения IIFE в моем глобальном объекте. У меня есть доступ к выражению функции и самому объекту, поэтому я могу передать или изменить что-то, чтобы заставить его работать (и нет, я не могу переписать все внутри объекта или функции).
Возможно ли это?
Ответы
Ответ 1
Единственный способ увидеть, насколько это возможно, с помощью eval
для имитации динамических областей. Сделайте это (обратите внимание, что IIFE должен быть помещен после глобального объекта):
window.myGlobalObj = {
init: function() {
// and somehow here I want to access to the IIFE context
}
};
(function() {
var a = 5;
var someFunc = function() { ... };
function anotherFunc() {
...
};
eval("(" + String(window.myGlobalObj.init) + ")").call(window.myGlobalObj);
})();
Вот ссылка как на использование динамических областей: Возможно ли достичь динамического охвата в JavaScript без использования eval?
Изменить: Я включил пример, демонстрирующий возможности использования динамических областей в JavaScript. Вы можете играть с fiddle.
var o = {
init: function () {
alert(a + b === this.x); // alerts true
},
x: 5
};
(function () {
var a = 2;
var b = 3;
eval("(" + String(o.init) + ")").call(o);
}());
Ответ 2
"Содержимое" вашего IIFE, т.е. a
, someFunc
и т.д., являются локальными для этой области действия, поэтому вы можете обращаться к ним только в пределах этой области. Но вы можете назначить window.myGlobalObj
внутри IIFE:
(function() {
var a = 5;
var someFunc = function() { ... };
function anotherFunc() {
...
};
window.myGlobalObj = {
init: function() {
// and somehow here I want to access to the IIFE context
}
};
})();
Тогда функция init
будет иметь доступ к этим переменным, так как они находятся в области с ее содержанием.
EDIT: если вы не можете переместить определение myGlobalObj
в IIFE, единственное, что я могу придумать, это использовать IIFE для создания второго глобального объекта, к которому вы обращаетесь, из myGlobalObj
:
(function() {
var a = 5;
var someFunc = function() { ... };
function anotherFunc() {
...
};
// create a global object that reveals only the parts that you want
// to be public
window.mySecondObject = {
someFunc : someFunc,
anotherFunc : anotherFunc
};
})();
window.myGlobalObj = {
init: function() {
window.mySecondObject.someFunc();
}
};
Ответ 3
Нет. Это невозможно. Контекст, к которому вы хотите получить доступ, называется closure
и может быть доступен только внутри функции (в вашем случае анонимная функция (IIFE, как вы ее называете)). Для получения дополнительной информации о закрытии следуйте отличным Douglas Crockfords Учебник по языку программирования Javascript.
Вам нужно будет поместить эти атрибуты в какой-то общий объект.