Можно ли передать контекст выполнения немедленно вызванного выражения функции
Рассмотрим следующий код:
(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 в моем глобальном объекте. У меня есть доступ к выражению функции и самому объекту, так что я могу передать или изменить что-то, чтобы заставить это работать (и нет, я не могу переписать все внутри объекта или функции).
Это вообще возможно?
3 ответа
Единственный способ понять, насколько это возможно, - использовать 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. Вы можете играть с скрипкой тоже.
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);
}());
"Содержимое" вашего 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
Функция будет иметь доступ к этим переменным, поскольку они находятся в своей области видимости.
РЕДАКТИРОВАТЬ: если вы не можете переместить определение 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();
}
};
Нет, это невозможно. Контекст, к которому вы хотите получить доступ, называется closure
и могут быть доступны только внутри функции (в вашем случае, анонимная функция (IIFE, как вы ее называете)). Чтобы узнать больше о замыканиях, следуйте великолепному видеоурору по языку программирования Javascript Дугласу Крокфорду.
Вы должны будете поместить эти атрибуты в некоторый общий объект.