-2

I was intrigued to read more about the eval() function at MDN , and encountered the following passsage

If the argument of eval() is not a string, eval() returns the argument unchanged.
In the following example, the String constructor is specified and eval() returns a String object rather than evaluating the string.

eval(new String('2 + 2')); // returns a String object containing "2 + 2"
eval('2 + 2');             // returns 4

It didn't make sense to me as "if eval doesn't evaluate its argument if it's not a string, then why did it create a new object instance !?"

2
  • "then why did it even create a new object instance": eval does not create a new object instance (when you give it an object). Why do you think that? Commented Dec 1, 2020 at 21:57
  • 2
    I wouldn't waste much time worrying about eval(). You can almost always do things a better way. Given the problems that eval() can introduce (code injection, more difficult debugging, and, allegedly, poor performance) spend your time elsewhere. Commented Dec 1, 2020 at 22:01

3 Answers 3

0

The type that is returned from new String('2 + 2') is "object".

console.log( typeof new String('2 + 2') )
console.log( typeof new String('2 + 2').toString() )

Since this is an object,

If the argument of eval() is not a string, eval() returns the argument unchanged.

If you specifically cast the String object to the string primitive with .toString(), it functions as you'd expect.

console.log(eval('2 + 2'));   
console.log(eval(new String('2 + 2')));
console.log(eval(new String('2 + 2').toString()));

Sign up to request clarification or add additional context in comments.

Comments

0

Your examples just works as they should.

Argument of the first eval is an object, not a primitive variable. String object in Javascript is explained in this question

eval(new String('2 + 2')); // So eval doesn't do anything here and return argument without any operation.

Argument of the second eval( is a pure string. No matter what's inside, eval will directly execute as a javascript code.

eval("new String(2+2)") // This will first calculate 2 + 2 and create a new string object with argument 4. 

Last one, it's a string, so eval will directly execute it as a javascript code as in the second example. The difference is, String object now accepts a string '2 + 2'

eval("new String('2 + 2')"); // returns a string object with a string argument. 

Hope this explanation helped.

2 Comments

yes , my problem is with the first and third example I.E., is that the it says eval() doesn't do anything and return the argument without any operations ; i interpreted that as the statement new String("2+2") will be literally returned in the console output , not a new String object like the output of the third example
Look, in the third example it's a string, eval doesn't care the content of the string but starts executing as javascript if it's a string, so the only one which will never be executed by eval is the first example. Others are interpreted as javascript lines.
0

It is quite straightforward. You can dissect eval as follows:

if (typeof argument === "string") return <evaluation of string>;
else return argument; // eval just returns what it gets

So your examples:

    eval(new String('2 + 2'));

You can split this into two statements:

let arg = new String('2 + 2');
console.log(typeof arg); // object
console.log(eval(arg) === arg); // true, because typeof arg is not "string"

The other two example pass a type string to eval:

let arg = "new String(2+2)";
console.log(typeof arg); // string
// Now we get evaluation of 2+2 and String constructor is called:
console.log(eval(arg)); // a String object (that's what the constructor produces)

In the third example, the string '2 + 2' is evaluated, which is the string "2 + 2". The rest is the same as the second example.

Note that a String object is not of type "string", but of type "object".

5 Comments

"// eval just returns what it gets" is see the explanation that way : internally if the argument is a string the interpreter execute the string argument -as part of the eval() function e.g., example 2 , 3, and if the argument is not enclosed in quotes the interpreter still execute it -separately- e.g.,example 1 , is that the how it works
sorry , forgot about callback functions
"...is not enclosed in quotes, the interpreter still executes it": that has nothing to do with eval;: if you would not wrap that expression with eval(), it would also evaluatenew String... That is how JS works: first the expression is evaluated. If that happens to be a string literal, there is nothing to it. If it happens to be a call of a constructor, then that call is executed. Once the expression has been evaluated, it is passed to eval. Only at that point eval does its thing: it the expression evaluated to string, then it is parsed and executed by eval.
I cam across my previous questions, and found some of them to be utterly useless and weird. There was others questions of mine that was discontinued without clear answer so i outright removed them. As for this question, the answer oddly enough makes no sense now. after some familiarity with js, i'm sure the more appropriate one has to do with how js parse and struct the control flow of tokens for invocation.
Did you realize my answer refered to a part of your question that you edited out in 2021? I can understand that as you read it now it makes little sense... as that connection is lost since that edit.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.