ReferenceError в Google Chrome, но не в Firefox (ошибка браузера?)
Этот фрагмент кода
eval(`
let a = 0;
function f() {}
function g() { a; }
console.log(f);
`);
Ответы
Ответ 1
Похоже, новая ошибка V8! Более минимальный тестовый пример:
eval(`
var f;
let a;
()=>a
`);
f;
Объявления с переменной областью (которые включают объявления функций верхнего уровня) не получают должным образом подняты из нестрогих вызовов eval
, когда вызов также имеет нетривиальное лексическое объявление.
Ответ 2
Тонкая настройка вашего примера показывает, что происходит, а команда немного противоречива, она выглядит как ошибка. Определите a как функцию и запишите его вместо f, а затем посмотрите на консоль. Вы увидите, что закрытие было создано с помощью a, f и g. Поскольку a ссылается на g, а f и g должны быть видны друг другу, это имеет немного смысл. Но eval работает в глобальном масштабе. Поэтому, когда вы пытаетесь получить к ним доступ, вы получаете undefined. Как будто это закрытие невозможно получить откуда угодно.
Try:
eval('let a = function(){}; function f() {};function g(){a;};console.dir(a);');
Вы увидите это в консоли:
<function scope>
Closure
a: function()
f: function f()
g: function g()
Все ваши другие случаи делают ситуацию более ясной и предотвращают проблему:
- eval не используется: несоответствие области менее очевидно,
- код внутри eval окружен {}: переменные связаны
через область блока.
- a не указывается в g: нет необходимости в закрытии, если переменные
не связаны.
- let изменено на var: var в глобальной области определяется в
глобальный охват. Таким образом, не требуется Closure
- "использовать строгий" добавляется перед кодом: используйте strict в eval prevent
переменные, которые должны быть добавлены в глобальную область действия, так что снова "проще"
ручка. Отсутствие несоответствия между необходимостью привязки к глобальным функциям.
Ответ 3
eval(`
"use strict";
let a = 0;
console.log(f);
function f(){
}
function g(){
a;
}
`);
Объявления с расширенной областью (let, const, function, class) еще не поддерживаются в строгом режиме