Выбрать главу

var geval = eval;         // Другое имя eval для вызова в глобальном контексте

var х = "global", у = "global"; // Две глобальные переменные

function f() { // Вызывает eval в локальном контексте

  var х = "local"; // Определение локальной переменной

  eval("x += 'changed';"); // Прямой вызов eval изменит локальную переменную

  return х; // Вернет измененную локальную переменную

}

function g() {     // Вызывает eval в глобальном контексте

  var у = "local"; // Локальная переменная

  geval("y += 'changed';") // Косвенный вызов eval изменит глоб. переменную

  return y;        // Вернет неизмененную локальную переменную

}

console.log(f(), х); //Изменилась локальная переменная: выведет "localchanged global":

console.log(g(), у); //Изменилась глобальная переменная: выведет "local globalchanged":

Обратите внимание, что обеспечение возможности вызывать функцию eval() в глобальном контексте - это не просто попытка удовлетворить потребности оптимизатора. Фактически это чрезвычайно полезная особенность: она позволяет выполнять строки с программным кодом, как если бы они были независимыми сценариями. Как уже отмечалось в начале этого раздела, действительная необходимость выполнять строки программного кода на практике возникает очень редко. Но если вы сочтете это необходимым, вам, скорее всего, потребуется вызывать функцию eval() именно в глобальном контексте, а не в локальном.

До появления версии IE9 Internet Explorer отличался от других броузеров: функцияeval(), вызванная под другим именем, выполняла переданный ей программный код не в глобальном контексте. (Однако она не возбуждала исключение EvalError: программный код просто выполнялся ею в локальном контексте.) Но IE определяет глобальную функцию execScript(), которая выполняет строку с программным кодом, переданную в виде аргумента, как если бы она была сценарием верхнего уровня. (Однако, в отличие от eval(), функция execScript() всегда возвращаетnull.)

4.12.3. Использование eval() в строгом режиме

Строгий режим (раздел 5.7.3), определяемый стандартом ECMAScript 5, вводит дополнительные ограничения на поведение функции eval() и даже на использование идентификатора «eval». Когда функция eval() вызывается из программного кода, выполняемого в строгом режиме, или когда строка, которая передается функции, начинается с директивы «use strict», то eval() выполняет программный код в частном окружении. Это означает, что в строгом режиме выполняемый программный код может обращаться к локальным переменным и изменять их, но он не может определять новые переменные или функции в локальной области видимости.

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

4.13. Прочие операторы

JavaScript поддерживает еще несколько операторов, которые описываются в следующих разделах.

4.13.1. Условный оператор (?:)

Условный оператор - это единственный тернарный (с тремя операндами) оператор в JavaScript, и иногда он так и называется - «тернарный оператор». Этот оператор обычно записывается как ?:, хотя в программах он выглядит по-другому. Он имеет три операнда, первый предшествует символу ?, второй - между ? и :, третий - после :. Используется он следующим образом:

х > 0 ? х : -х // Абсолютное значение х

Операнды условного оператора могут быть любого типа. Первый операнд вычисляется и используется как логическое значение. Если первый операнд имеет истинное значение, то вычисляется и возвращается значение выражения во втором операнде. Если первый операнд имеет ложное значение, то вычисляется и возвращается значение выражения в третьем операнде. Вычисляется всегда только какой-то один операнд, второй или третий, и никогда оба.