为什么eval()中的typeof在我的函数中引发错误?

时间:2019-04-03 14:15:43

标签: javascript eval

我正在尝试实现类似于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:我已经读过Why does typeof only sometimes throw ReferenceError?,但我认为情况不尽相同,这里我不是在检查表达式,而只是在检查标识符。

1 个答案:

答案 0 :(得分:10)

这实际上与eval()没有关系。您的错误是由定义let obj引起的,但是在定义之前尝试使用它。 here描述了此异常:

  

但是,通过添加块范围的let和const,在声明它们之前在块中使用let和const变量上的typeof(或在类上使用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 = {},您的错误就会消失。