Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does typeof within eval() throw an error in my function?

I was trying to implement a function similar to angular.isDefined(...)

but allowing to check variables and their properties, so I wrote this proof of concept:

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');

I know that typeof allows a non declared identifier, and it seems to work properly within eval():

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

But in my code fails when it is processed by eval(). What am I missing?

PS: I've read Why does typeof only sometimes throw ReferenceError? but I think it is not the same scenario, I am not checking an expression here, but just a identifier.

like image 517
Pablo Lozano Avatar asked Apr 03 '19 14:04

Pablo Lozano


People also ask

What error type is thrown if you have an error in the eval () function?

An EvalError indicates an error in the eval() function. Newer versions of JavaScript do not throw EvalError. Use SyntaxError instead.

Why is it bad to use eval in JavaScript?

eval() is a dangerous function, which executes the code it's passed with the privileges of the caller. If you run eval() with a string that could be affected by a malicious party, you may end up running malicious code on the user's machine with the permissions of your webpage / extension.

Why eval is not recommended?

Malicious code : invoking eval can crash a computer. For example: if you use eval server-side and a mischievous user decides to use an infinite loop as their username. Terribly slow : the JavaScript language is designed to use the full gamut of JavaScript types (numbers, functions, objects, etc)… Not just strings!

What is a safe alternative to using eval ()?

An alternative to eval is Function() . Just like eval() , Function() takes some expression as a string for execution, except, rather than outputting the result directly, it returns an anonymous function to you that you can call. `Function() is a faster and more secure alternative to eval().


1 Answers

This actually has nothing to do with eval(). Your error is caused by defining let obj but trying to use it before it is defined. This exception is described here:

But with the addition of block-scoped let and const, using typeof on let and const variables (or using typeof on a class) in a block before they are declared will throw a ReferenceError. Block scoped variables are in a "temporal dead zone" from the start of the block until the initialization is processed, during which, it will throw an error if accessed

You can cause this error easily without 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 = {}

Your error goes away if you remove the let obj={}; declaration or use var obj = {}.

like image 168
Mark Avatar answered Oct 18 '22 03:10

Mark