Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript eval alias

Tags:

javascript

Does javascript allow aliasing eval? The first part of the following code behaves unexpectedly (displays 1, 1), but the second part does not (displays 1, 2). A reference to the ECMA script or mozilla docs will be helpful, I couldn't find one.

<html>
<script type="application/javascript;version=1.8">
    (function(){
        eval('var testVar=1');
        alert(testVar);
        var eval2=eval;
        eval2('var testVar=2');
        alert(testVar);
    })();

    (function(){
        eval('var testVar=1');
        alert(testVar);
        eval('var testVar=2');
        alert(testVar);
    })();
</script>
</html>
like image 447
simonzack Avatar asked Jul 21 '13 09:07

simonzack


People also ask

Is eval bad practice JavaScript?

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)…

Why we should not 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.

What is $$ eval?

$$eval() method. This method runs Array. from(document. querySelectorAll(selector)) within the page and passes the result as the first argument to the pageFunction .

What can I use instead of eval in JavaScript?

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().


2 Answers

You can't "alias" eval and expect it to behave the same. Simple as that. Why? eval isn't a function.

What is happening is that when you call eval2, you are setting the variable "cache" to work with the global variables. Therefore, by setting a variable inside of it, you are setting a global variable. However, upon exiting, the variable "cache" returns back to the function scoped one. That's why the second alert shows 1 - the global variable is being shadowed by the function level one.

This is noted in Annex E (page 239) of ECMAScript (emphasis mine)

10.4.2: In Edition 5, indirect calls to the eval function use the global environment as both the variable environment and lexical environment for the eval code. In Edition 3, the variable and lexical environments of the caller of an indirect eval was used as the environments for the eval code.

The full definition on "Entering Eval Code" is defined in §10.5.2 (page 58) (emphasis mine)

  1. If there is no calling context or if the eval code is not being evaluated by a direct call (15.1.2.1.1) to the eval function then,
    • Initialise the execution context as if it was a global execution context using the eval code as C as described in 10.4.1.1.
  2. Else,
    • Set the ThisBinding to the same value as the ThisBinding of the calling execution context.
    • Set the LexicalEnvironment to the same value as the LexicalEnvironment of the calling execution context.
    • Set the VariableEnvironment to the same value as the VariableEnvironment of the calling execution context.
  3. If the eval code is strict code, then
    • Let strictVarEnv be the result of calling NewDeclarativeEnvironment passing the LexicalEnvironment as the argument.
    • Set the LexicalEnvironment to strictVarEnv.
    • Set the VariableEnvironment to strictVarEnv.
  4. Perform Declaration Binding Instantiation as described in 10.5 using the eval code.
like image 76
Cole Tobin Avatar answered Sep 20 '22 20:09

Cole Tobin


In the first case when you use eval, it uses the function scope within which it is executed. When you assign eval to eval2 and then execute the same statement, it seems to be using the window context(global scope) and not the function context. That's why you see the same value 1 in the first case because testVar inside the function is 1 and outside window.testVar is 2. You can prove this by executing the below snippet

<script>
(function(){
        eval('var testVar=1');
        alert(window.testVar);
        var eval2=eval;

        eval2('var testVar=2');
        alert(window.testVar);
    })();

    (function(){
        eval('var testVar=1');
        alert(testVar);
        eval('var testVar=2');
        alert(testVar);
    })();
</script>

Actually, as per Mozilla Developer Network, you can't alias eval.

like image 28
mohkhan Avatar answered Sep 17 '22 20:09

mohkhan