【问题标题】:Why does typeof within eval() throw an error in my function?为什么 eval() 中的 typeof 会在我的函数中引发错误?
【发布时间】:2019-04-03 14:15:42
【问题描述】:

我试图实现类似于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? 但我认为这不是同一个场景,我这里不是检查表达式,而只是一个标识符。

【问题讨论】:

  • 这真的很有趣。这是一个较小的复制品:eval('typeof obj'); let obj;。这会引发 ReferenceError,但如果您删除 let obj,错误就会消失,eval 按预期返回 'undefined'。在eval 之前移动let obj 也会使错误消失,这让我认为这与提升有关。
  • @JordanRunning 如果您将let 更改为var,代码将按预期工作。很有趣。

标签: javascript eval


【解决方案1】:

这实际上与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 = {},您的错误就会消失。

【讨论】:

  • 有关let 问题的更多信息,关于Temporal Dead Zone 的Mozilla 网络文档在这种情况下非常有用。
猜你喜欢
  • 2021-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-21
  • 1970-01-01
  • 2016-12-02
相关资源
最近更新 更多