Можно ли передать контекст выполнения немедленно вызванного выражения функции

Рассмотрим следующий код:

<code>(function() {
    var a = 5;
    var someFunc = function() { ... };
    function anotherFunc() {
        ...
    };
})();

window.myGlobalObj = {
    init: function() {
        // and somehow here I want to  access to the IIFE context
    }
};
</code>

Я хочу иметь контекст выполнения IIFE в моем глобальном объекте. У меня есть доступ к выражению функции и самому объекту, так что я могу передать или изменить что-то, чтобы заставить это работать (и нет, я не могу переписать все внутри объекта или функции).

Это вообще возможно?

 Zirak23 апр. 2012 г., 13:04
Если вы не можете перенести его содержимое или изменить его, тогда вы просто не сможете этого сделать.
 Ilya Tsuryev23 апр. 2012 г., 12:53
@Tomas, вызовите someFunc, anotherFunc, используйте переменную «a».
 TMS23 апр. 2012 г., 12:44
какой IIFE? Пожалуйста, будьте ясны
 kapa23 апр. 2012 г., 12:45
Выражение функции немедленного вызова @Tomas
 TMS23 апр. 2012 г., 12:46
показать пример того, что вы имеете в виду под «доступом к контексту IIFE». Как бы вы получили к нему доступ.

Ответы на вопрос(3)

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();
    }
};
 23 апр. 2012 г., 23:45
Да, вам нужно перечислить "общедоступный" из них. Но обратите внимание, что «общедоступный» Сами они будут иметь доступ к «частным» из них.
 23 апр. 2012 г., 13:04
Хорошо извини Я обновил свой ответ единственной вещью, о которой я могу думать ...
 Ilya Tsuryev23 апр. 2012 г., 12:54
Теперь это будет работать, но я не могу переписать все внутри объекта (или в этом случае внутри IIFE).
 Ilya Tsuryev23 апр. 2012 г., 13:06
@ Редактировать: я должен был бы перечислить все переменные и функции, к которым я хочу получить доступ, верно? :(

это невозможно. Контекст, к которому вы хотите получить доступ, называетсяclosure и могут быть доступны только внутри функции (в вашем случае, анонимная функция (IIFE, как вы ее называете)). Для получения дополнительной информации о закрытиях следуйтеДуглас Крокфордс Видеоурок по языку программирования Javascript.

Вы должны будете поместить эти атрибуты в некоторый общий объект.

 23 апр. 2012 г., 13:43
Я извиняюсь. Как именно мой код может причинить вред? Если вы сможете доказать мне в разумных пределах, что есть лучший способ решить эту проблему без использованияeval тогда, пожалуйста, пообещай мне. Я не вижу, как использоватьeval в этом случае может привести к небезопасному коду. Не говорите мне, что я не прав. Покажите мне с тестовым примером.
 23 апр. 2012 г., 13:39
Это не очень плохая практика. Там очень много страха среди программистов, когда дело доходит доeval и в большинстве случаев это связано с тем, что программисты не знают, как это вредно. Однако в правильных руках это безопасный и мощный инструмент. Подумайте об этом - если это действительно так плохо, то почему бы вообще не удалить его из языка? Это все еще существует в EC5. С помощьюeval для моделирования динамических областей является одним из тех случаев, когдаeval не зло В этом случае использования невозможно сломать существующий код - если только программист не умышленно испортит то, чего, по всей вероятности, никогда не будет.
 23 апр. 2012 г., 13:37
С вашим ответом вы практически показали, что я был прав - это невозможно (within reasonably sane code).
 23 апр. 2012 г., 13:31
@AaditMShah, это действительно было бы плохой практикой! Я бы назвал это грязным хаком и запретил бы его. Кстати, использование eval в jQuery для синтаксического анализа JSON считается большим недостатком, и jQuery подвергается критике за это. Вот почему лучше всего использоватьDouglas Crockford's json2.js для этой цели.
 23 апр. 2012 г., 13:25
На самом деле это возможно. Все, что вам нужно сделать, это моделировать динамические области в JavaScript, используяeval, я знаю этоeval считается злом, но бывают случаи, когда это необходимо. Даже JQuery используетeval, Имитация динамических областей в JavaScript - один из тех случаев, когда его действительно безопасно использоватьeval, Вы можете прочитать больше об этом здесь:Is it possible to achieve dynamic scoping in JavaScript without resorting to eval?
Решение Вопроса

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?

Edit: Я включил пример, чтобы продемонстрировать мощь использования динамических областей в 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);
}());
 24 апр. 2012 г., 09:05
@ Stonerain, вы только что узнали довольно неприятную вещь. Избегай это! Мастера, такие как Дуглас Крокфорд, недовольны Эвалом. Код ужасен, труден для понимания и отладки, неэффективен и создает другие опасности. Использование его для этой цели является злоупотреблением.
 23 апр. 2012 г., 13:51
Рад помочь. Существует множество хаков, которые можно использовать, если вы хотите больше узнать оeval и как это можно безопасно использовать. Например, вы можете реализоватьpointers в JavaScript с помощьюeval.
 24 апр. 2012 г., 13:01
@ Томас, я думаю, что это слишком резко. Функцияeval сам Дуглас Крокфорд не осуждает себя. Это неправильное использование этой функции программистами-любителями, что вызывает проблемы. Большинство случаев использованияeval может быть достигнуто без этого. Тем не менее, есть некоторые случаи использования, которые действительно требуютeval, При правильном использованииeval это безопасный инструмент. Я говорил это раньше, и я скажу это снова - большинствоfear относительноeval только из-за невежества. Не винитеeval для плохих программ.
 24 апр. 2012 г., 13:22
@Aadit, спасибо заlink you posted, Я могу только согласиться с этим:"All such unnecessary uses of eval add to a maintenance hell. Refactoring tools are thrown off. Searching for code is hard. Unanticipated effects of those evals are legion."
 Ilya Tsuryev23 апр. 2012 г., 13:44
Хотя я на самом деле не буду использовать такую схему в приложении, но это было очень интересно, узнал что-то новое!

Ваш ответ на вопрос