Этот фрагмент кода
eval(`
let a = 0;
function f() {}
function g() { a; }
console.log(f);
`);Этот фрагмент кода
eval(`
let a = 0;
function f() {}
function g() { a; }
console.log(f);
`);Похоже, новая ошибка V8! Более минимальный тестовый пример:
eval(`
var f;
let a;
()=>a
`);
f;
Объявления с переменной областью (которые включают объявления функций верхнего уровня) не получают должным образом подняты из нестрогих вызовов eval, когда вызов также имеет нетривиальное лексическое объявление.
Тонкая настройка вашего примера показывает, что происходит, а команда немного противоречива, она выглядит как ошибка. Определите 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(`
"use strict";
let a = 0;
console.log(f);
function f(){
}
function g(){
a;
}
`);
Объявления с расширенной областью (let, const, function, class) еще не поддерживаются в строгом режиме