Что такое контекст вызова?

ECMA-262 5.1, подразделы 10.4.2 и 10.4.2.1 относится к контексту вызова. Похоже, это больше нигде в документе не описано.

Цитируя спецификацию, акцент мой:

10.4.2 Ввод оценочного кода

Следующие шаги выполняются, когда элемент управления входит в контекст выполнения для кода eval:

  1. Если нет вызывающего контекста или если код eval не оценивается прямым вызовом (15.1.2.1.1) функции eval, тогда

10.4.2.1 Ограничения строгого режима

Код eval не может создавать экземпляры переменных или привязок функций в среде переменных вызывающего контекста, которая вызвала eval, если либо код вызывающего контекста, либо код eval является строгим кодом. . Вместо этого такие привязки создаются в новой среде VariableEnvironment, которая доступна только для кода eval.

  • Что означает контекст вызова в этих абзацах? Я предполагаю, что это относится к Контексту выполнения вверху. стека непосредственно перед вызовом eval; кто-нибудь может это проверить?

  • Что означает отсутствие контекста вызова? Может ли кто-нибудь предоставить пример кода или условий, которые могут привести к вызову eval без контекста вызова?


person Dagg Nabbit    schedule 11.01.2014    source источник


Ответы (1)


«Контекст вызова» относится к контексту, из которого вызывается собственная функция eval.

Если вы выполняете eval из какого-то нативного кода (например, вы запускаете нативную функцию, которая выполняет код после завершения с использованием eval по той или иной причине), тогда у нее не будет контекста, который затем указывается для запуска в глобальной области. Контекст относится только к исполняемому коду ECMAScript.

Однако контекст вызова относится к переменным и директивам в контексте выполнения того места, где он вызывается. Например, он знает, что eval должен работать как строгий код, только если он проверяет контекст вызова.

Это проясняется очень похожим вопросом в списке рассылки ES-Discuss, где Брендан Эйх (создатель JavaScript) отвечает:

Как может код eval не иметь контекста вызова?< /а>

ЕС3 говорит:

10.2.2 Оценочный код

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

Меня сбивает с толку «Если нет контекста вызова». Как могла возникнуть такая возможность? Как будет вызываться eval, если его никто не вызывает?

Ответ:

Вызов из нативного кода, "хозяйской" программы.

Некоторые браузеры поддерживают косвенные eval, что позволяет:

setTimeout(eval, 0, "alert('hi mom')");

Используемое окно — это то, в котором setTimeout было найдено в цепочке областей видимости, поэтому

myFrame.setTimeout(eval, 0, "alert(x)");

должен показывать myFrame.x, а не вызывающий фрейм или окно x.

Примечание. myFrame в данном случае относится к глобальной области фрейма.

person Qantas 94 Heavy    schedule 11.01.2014
comment
Это звучит правильно для меня, хотя я думаю, что часть глобальной области видимости отключена; глобальная область имеет контекст выполнения (когда управление передается исполняемому коду ECMAScript, управление входит в контекст выполнения). Хорошая мысль о том, что контекст выполнения применяется только к сценарию; например, консоль вызывает eval без контекста вызова. Это может быть вашим предположением, к сожалению, так же хорошо, как и мой сценарий, поскольку в спецификации нет точного описания контекста вызова. Посмотрим, появятся ли другие ответы. - person Dagg Nabbit; 11.01.2014
comment
@DaggNabbit: я думаю, что то, где он используется в разделе строгого режима, немного более понятно, именно так я об этом думал. - person Qantas 94 Heavy; 11.01.2014
comment
@DaggNabbit: какой-то гугл-фу нашел что-то очень близкое к официальному ответу, так лучше? - person Qantas 94 Heavy; 11.01.2014
comment
Ого, ES3 намного точнее описывает контекст вызова. Кажется, я чувствую, что назревает еще один вопрос. До сих пор читаю это... - person Dagg Nabbit; 11.01.2014
comment
Если вы проголосовали за этот пост, не могли бы вы объяснить, как я могу улучшить этот пост или что с ним не так? Спасибо! - person Qantas 94 Heavy; 11.01.2014
comment
Мне также было бы интересно услышать объяснение отрицательного голоса. Я чувствовал, что этот ответ охватывает все, но если чего-то не хватает, я хотел бы это услышать. - person Dagg Nabbit; 11.01.2014
comment
Этот ответ твердый и правильный. Кто бы ни проголосовал за него, должно быть, он был зол лично на вас @Qantas94Heavy - person Benjamin Gruenbaum; 12.01.2014