Чтение онлайн

на главную - закладки

Жанры

JavaScript. Подробное руководство, 6-е издание
Шрифт:

Ключевой особенностью функции

eval
(когда она вызывается таким способом) является то обстоятельство, что она использует окружение программного кода, вызвавшего ее. То есть она будет отыскивать значения переменных и определять новые переменные и функции, как это делает локальный программный код. Если функция определит локальную переменную х и затем вызовет
eval("x”),
она получит значение локальной переменной. Вызов
eval( "x=1")
изменит значение локальной переменной. А если выполнить вызов
eval("vaг у = 3; ”),
будет объявлена новая локальная переменная
у
. Точно так же можно определять новые локальные функции:

eval("function f { return x+1; }");

Если вызвать функцию

eval
из программного кода верхнего уровня, она, разумеется, будет оперировать глобальными переменными и глобальными функциями.

Обратите внимание, что программный код в строке, передаваемой функции

eval,
должен быть синтаксически осмысленным - эту функцию нельзя использовать, чтобы вставить фрагмент программного кода в вызывающую функцию. Например, бессмысленно писать вызов
eval("return;"),
потому что инструкция
return
допустима только внутри функций, а тот факт, что программный код в строке использует то же самое окружение, что и вызывающая функция, не делает его частью этой функции. Если программный код в строке может расцениваться как самостоятельный сценарий (пусть и очень короткий, такой как
х=0
), его уже можно будет передавать функции
eval.
В противном случае
eval
возбудит исключение
SyntaxError
.

4.12.2. Использование eval в глобальном контексте

Способность функции

eval
изменять локальные переменные представляет значительную проблему для оптимизаторов JavaScript. Для ее решения некоторые интерпретаторы просто уменьшают степень оптимизации всех функций, вызывающих
eval.
Однако как быть интерпретатору JavaScript, когда в сценарии определяется псевдоним функции
eval
и выполняется ее вызов по другому имени? Чтобы облегчить жизнь разработчикам интерпретаторов JavaScript, стандарт ECMAScript 3 требует, чтобы такая возможность в интерпретаторах была запрещена. Если функция
eval
вызывается под любым другим именем, отличным от «eval», она должна возбуждать исключение
EvalError
.

Однако большинство разработчиков используют иные решения. При вызове под любым другим именем функция

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

Стандарт ECMAScript 5 отменяет возбуждение исключения

EvalError
и стандартизует поведение
eval,
сложившееся де-факто. «Прямой вызов» - это вызов функции
eval
по ее непосредственному имени «eval» (которое все больше начинает походить на зарезервированное слово). Прямые вызовы
eval
используют окружение вызывающего контекста. Любые другие вызовы - косвенные вызовы - в качестве окружения используют глобальный объект и не могут получать, изменять или определять локальные переменные или функции. Это поведение демонстрируется в следующем фрагменте:

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 поддерживает еще несколько операторов, которые описываются в следующих разделах.

Поделиться:
Популярные книги

Кодекс Охотника. Книга XXVII

Винокуров Юрий
27. Кодекс Охотника
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XXVII

Иной. Том 5. Адская работа

Amazerak
5. Иной в голове
Фантастика:
боевая фантастика
городское фэнтези
технофэнтези
рпг
5.00
рейтинг книги
Иной. Том 5. Адская работа

Протокол "Наследник"

Лисина Александра
1. Гибрид
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Протокол Наследник

Кодекс Крови. Книга VI

Борзых М.
6. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Крови. Книга VI

Стеллар. Трибут

Прокофьев Роман Юрьевич
2. Стеллар
Фантастика:
боевая фантастика
рпг
8.75
рейтинг книги
Стеллар. Трибут

Хозяин Теней 4

Петров Максим Николаевич
4. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней 4

Князь Целитель 5

Ткачев Андрей Юрьевич
5. Князь Целитель
Фантастика:
боевая фантастика
городское фэнтези
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Князь Целитель 5

Приказано выжить!

Малыгин Владимир
1. Другая Русь
Фантастика:
боевая фантастика
попаданцы
альтернативная история
7.09
рейтинг книги
Приказано выжить!

Иной. Том 1. Школа на краю пустыни

Amazerak
1. Иной в голове
Фантастика:
боевая фантастика
рпг
аниме
5.75
рейтинг книги
Иной. Том 1. Школа на краю пустыни

Ученик. Книга 4

Первухин Андрей Евгеньевич
4. Ученик
Фантастика:
фэнтези
5.67
рейтинг книги
Ученик. Книга 4

Мятежник

Прокофьев Роман Юрьевич
4. Стеллар
Фантастика:
боевая фантастика
7.39
рейтинг книги
Мятежник

Третий. Том 6

INDIGO
Вселенная EVE Online
Фантастика:
боевая фантастика
космическая фантастика
фантастика: прочее
попаданцы
5.00
рейтинг книги
Третий. Том 6

Воронцов. Перезагрузка. Книга 2

Тарасов Ник
2. Воронцов. Перезагрузка
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Воронцов. Перезагрузка. Книга 2

Путь Шедара

Кораблев Родион
4. Другая сторона
Фантастика:
боевая фантастика
6.83
рейтинг книги
Путь Шедара