Почему typeof в eval () вызывает ошибку в моей функции? - PullRequest
10 голосов
/ 03 апреля 2019

Я пытался реализовать функцию, подобную angular.isDefined(...)

но позволяя проверить переменные и их свойства, поэтому я написал это доказательство концепции:

function check(s) {
  let parts = s.split('\.');
  let partial = '';

  return parts.every(p => { 
    partial += (partial ? '.': '') + p;
    let expr = `typeof ${partial}`;
    console.log('Evaluating', expr);
    return eval(expr) !== 'undefined';
  });
}

check('obj');
let obj={};
check('obj');
obj.a=1;
check('obj.a');

Я знаю, что typeof допускает необъявленный идентификатор, и, похоже, он правильно работает в eval():

console.log(typeof someVariableWhichDoesNotExists)
console.log(eval('typeof someVariableWhichDoesNotExists'));

Но в моем коде происходит сбой, когда он обрабатывается eval(). Чего мне не хватает?

PS: я прочитал Почему typeof только иногда выдает ReferenceError? , но я думаю, что это не тот же сценарий, я не проверяю здесь выражение, а просто идентификатор.

1 Ответ

10 голосов
/ 03 апреля 2019

Это на самом деле не имеет ничего общего с eval().Ваша ошибка вызвана определением let obj, но попыткой использовать его до того, как оно будет определено.Это исключение описано здесь :

Но с добавлением блока let-и-const в области видимости, используя переменные typeof для let и const (или используя typeof для класса) вблок, прежде чем они будут объявлены, выдаст ReferenceError.Переменные области видимости находятся в «временной мертвой зоне» от начала блока до обработки инициализации, во время которой будет возникать ошибка при обращении

Вы можете легко вызвать эту ошибку без eval():

// undefined no problem because obj was not declared
console.log(typeof obj)

// undefined but variable declared with let
// but not defined before using it results in an error
console.log(typeof otherobj)
let otherobj = {}

Ваша ошибка исчезнет, ​​если вы удалите декларацию let obj={}; или используете var obj = {}.

...