JavaScript: ссылка на локальную область функций как на объект

Когда я вызываю функцию, для этого вызова создается локальная область видимости. Есть ли способ напрямую ссылаться на эту область как на объект? Точно так же, как окно является ссылкой на объект глобальной области видимости.

Пример:

function test(foo){
    var bar=1
    //Now, can I access the object containing foo, bar, arguments and anything
    //else within the local scope like this:
    magicIdentifier.bar
}

В качестве альтернативы, есть ли у кого-нибудь полный список того, что находится в локальной области помимо пользовательских переменных?

Предыстория: я пытаюсь перейти к полному переходу на глобальную область видимости из вызова функции, оператор with — это шутка, вызов работает немного лучше, но он по-прежнему ломается для всего, что объявлено в области функции, но не в глобальная область действия, поэтому я бы объявил эти несколько случаев в глобальной области видимости, но для этого мне нужно знать, что они из себя представляют. Функция execScript в IE делает полный сдвиг, но это решает проблему только для IE.

Примечание. Для всех, кто загружает JavaScript динамически, setTimeout(code,1) — это простой эффективный способ достижения глобальной области видимости, но он не будет выполняться немедленно.


person aaaaaaaaaaaa    schedule 08.04.2010    source источник
comment
Если вам нужно получить доступ к объекту, содержащему аргумент foo внутри функции, почему бы не передать этот объект напрямую в качестве аргумента?   -  person Darin Dimitrov    schedule 08.04.2010
comment
@aaaaaaaaaaaaa Вы когда-нибудь находили жизнеспособное решение для этого? Мне было бы очень интересно, особенно решение, которое работает и для переменных с блочной областью БЕЗ использования eval() или new Function().   -  person Brandon McConnell    schedule 03.06.2021


Ответы (5)


Нет, нет способа сослаться на переменный объект контекста выполнения функции объект привязки переменной среды выполнения контекст (именно так эта штука называется [сейчас; отсюда зачеркнуто]; подробности в §10.3 спецификации). Вы можете получить доступ только к ограниченному виду, который вы получаете с помощью arguments (который действительно очень ограничен).

Обычно, когда я хотел это сделать, я просто помещал все, что хотел, в объект, а затем использовал это (например, передал это в функцию). Конечно, любые функции, созданные в контексте, имеют доступ ко всему в той области, в которой они созданы, поскольку они «закрывают» контекст; подробнее: Замыкания не сложны.

person T.J. Crowder    schedule 08.04.2010
comment
Ничего себе, эти спецификации действительно больно читать. В любом случае, насколько я могу судить, они предполагают, что единственными локальными переменными, помимо параметров и определенных локальных переменных, являются аргументы и длина. Это должно заставить меня двигаться, спасибо. Я создаю библиотеку, и первая функция, которую я создаю, — это согласованная версия setInterval, для чего она и предназначена. Кажется, что все становится намного сложнее, когда у вас есть такой блестящий абстрактный интерфейс. - person aaaaaaaaaaaa; 08.04.2010
comment
@eBusiness: Да, да, это так. :-) Не забывайте о любых именованных функциях, объявленных внутри функции, они также являются символами в области видимости. - person T.J. Crowder; 08.04.2010

Я знаю, что это очень поздно, и вы, вероятно, даже немного не заинтересованы, но меня тоже интересовала возможность этого, и вы должны быть в состоянии сделать какую-то работу, используя:

(function(global) {
    var testVar = 1;

    global.scope = function(s) {
        return eval(s);
    }
})(this);

затем работает:

scope('testVar'); // 1

возвращает переменную из замыкания. Не особенно приятно, но теоретически возможно обернуть это в объект, возможно, используя некоторую проверку и геттеры и сеттеры, если вам нужно?

Изменить: перечитав вопрос, я предполагаю, что вы захотите получить к нему доступ без необходимости указывать функцию в самой области, поэтому это, вероятно, неприменимо. Я все равно оставлю это здесь.

person Dom Hastings    schedule 07.03.2014
comment
Я думаю, это гениально! - person Gershy; 10.10.2017

В некоторых версиях Netscape в объекте arguments было волшебное свойство, которое делало то, что вы ищете. (не помню как называлась)

person SLaks    schedule 08.04.2010
comment
arguments — это переменная, содержащая все аргументы, переданные текущей функции. - person nickf; 08.04.2010
comment
@nickf: я это понимаю. В некоторых версиях Netscape у него было специальное свойство, относящееся к области видимости переменных. - person SLaks; 08.04.2010
comment
@nickf: Сначала я тоже неправильно его прочитал, но, зная SLaks, я прочитал его во второй раз и понял, что он имел в виду. :-) - person T.J. Crowder; 08.04.2010
comment
Интересно, но я боюсь, что то, что доступно в некоторых версиях Netscape, просто не годится для современной веб-разработки ;-) - person aaaaaaaaaaaa; 08.04.2010
comment
Возможно, он все еще существует в Firefox. Однако вы правы; это на самом деле не поможет вам. - person SLaks; 08.04.2010

Как насчет чего-то подобного?

<script type="text/javascript">
    var test =  {
        bar : 1,
        foo : function () {
            alert(this.bar);
        }
    }

    test.foo();
</script>
person Ivo Sabev    schedule 08.04.2010
comment
Если бы моей целью было просто написать странный код, это было бы хорошим решением :-) - person aaaaaaaaaaaa; 08.04.2010
comment
Ржу не могу. Я не понимаю, как это странно, поскольку вы просто создаете простую структуру классов. - person Ivo Sabev; 08.04.2010

Вам не нужно ключевое слово для ссылки на переменную в локальной области, потому что это область, в которой вы находитесь.

person Matt Ball    schedule 08.04.2010
comment
Перебирать каждую переменную, существующую в текущей области видимости? Для меня это не звучит как Javascript (или что-то вроде Javascript-аналога слова Pythonic). - person Matt Ball; 08.04.2010
comment
Отсутствие объекта, который ссылается на локальные переменные, кажется мне не-Javascript. Мне это не нужно, но я ожидаю, что он будет существовать, у JavaScript, похоже, есть объекты почти для всего, и все они связаны с объектами. - person Rolf; 05.12.2013
comment
@Rolf Я должен с уважением не согласиться. Мне это не кажется не-JS-y. Такой объект также не нужен. Когда вам действительно, действительно нужен динамический доступ к переменной – и вы действительно, действительно уверены, что не должны использовать {} (выделенный объект) – есть всегда eval чтобы вернуться. - person Matt Ball; 05.12.2013