Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

'eval var' in class method not work #28174

Closed
andersonlunog opened this issue Jun 11, 2019 · 5 comments
Closed

'eval var' in class method not work #28174

andersonlunog opened this issue Jun 11, 2019 · 5 comments
Labels
question Issues that look for answers.

Comments

@andersonlunog
Copy link

Code:

function compareOut(obj, pattern) {
  for (const k in obj) {
    eval(`var ${k} = obj.${k};`);
  }
  return eval(`${pattern};`);
}

class Comparator {
  compareIn(obj, pattern) {
    for (const k in obj) {
      eval(`var ${k} = obj.${k};`);
    }
    return eval(`${pattern};`);
  }
  compare() {
    var pattern = 'name == "Nogueira"';
    var obj = {
      name: "Nogueira"
    }
    try {
      console.log("Result Test 1: " + compareOut(obj, pattern));
      console.log("Result Test 2: " + this.compareIn(obj, pattern));
    } catch (error) {
      console.error(error);
    }
  }
}

var c = new Comparator();
c.compare();

Expected result

Result Test 1: true
Result Test 2: true

But received

Result Test 1: true
ReferenceError: name is not defined
@mscdex
Copy link
Contributor

mscdex commented Jun 11, 2019

Class methods are implicitly executed in strict mode and in strict mode eval() only creates variables that are available within the code passed to eval(). That is why you see the ReferenceError.

@mscdex mscdex closed this as completed Jun 11, 2019
@mscdex mscdex added the question Issues that look for answers. label Jun 11, 2019
@retorquere
Copy link

So this in the main script scope should work?

eval('const x = 1');
console.log(x);

because that still gives me a ReferenceError.

@Trott
Copy link
Member

Trott commented Jun 17, 2019

So this in the main script scope should work?

eval('const x = 1');
console.log(x);

because that still gives me a ReferenceError.

That should give you a ReferenceError. x in the console.log() call doesn't know anything about x in the eval() call. const scoping is much more narrow than var. Change it to var and it will work. This has nothing to do with Node.js specifically. The browser console will show the same results.

@retorquere
Copy link

Ah, I thought eval ran the code in the current scope, but it doens't fully then?

@Trott
Copy link
Member

Trott commented Jun 17, 2019

Ah, I thought eval ran the code in the current scope, but it doens't fully then?

IIUC, it runs in the current local scope (unless, for example, invoked by a reference, see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Description) but it creates its own block scope inside of that. So const and let do not leak, but var does.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Issues that look for answers.
Projects
None yet
Development

No branches or pull requests

4 participants