Этот фрагмент кода
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) еще не поддерживаются в строгом режиме