ECMA-262 Standard JS, the difference between Eval and window.eval

Source: Internet
Author: User
Tags eval goto

It looks very simple and runs correctly. A of the Eval declaration is only visible internally; Window.eval declared B is globally visible.

The code is as follows Copy Code

<script>
function A ()
{
Eval ("var a=1");
Window.eval ("var b=1");
}

A ();

Alert (typeof a); Undefined
Alert (typeof B); Number
</script>

But it was a bit weird to think about it afterwards. Eval and window.eval are not the same function, why add window. Meaning is different? If Eval internally determines the current this, then when Eval and Window.eval execute, this is all pointing to window.

If you use a variable p=window.eval, is P () and Window.eval () still the same?

  code is as follows copy code

<script
Function A ()
{
    var p = window.eval;

    alert (p = = window.eval);   //true
    alert (p = = eval);           //true

    eval ("var a=1");
    p ("var b=1");
}

A ();

Alert (typeof a);   //undefined
Alert (typeof b);   //number
</script

Tested, P () and window.eval () effect exactly the same, are all in the global execution. and p = = = Window.eval and P = = eval are set up at the same time! It's obviously strange, but there's something even more strange in the back! If we use q=eval, the result is completely unexpected:

The code is as follows Copy Code

<script>
function A ()
{
var p = window.eval;
var q = eval;

P ("var a=1");
Q ("var b=1");
}

A ();

Alert (typeof a); Number
Alert (typeof B); Number
</script>

All the number! are showing. In other words, pointing to eval p, the actual effect is window.eval. They are all executing code in the global!

To verify the difference between references, let's do one more test:

The code is as follows Copy Code

<script>
function A ()
{
var q = eval;

Q ("var b=1");
Eval ("var a=1");
}

A ();

Alert (typeof a); Undefined
Alert (typeof B); Number
</script>

Obviously, eval execution's A is left inside, while Q=eval B is global!

So I speculate that the eval in standard JavaScript, like this, is both a keyword and a variable (a function variable). If the keyword is invoked, that is, the literal eval (), then executes in the current context, otherwise, by invoking the variable reference, it is executed globally. This explains the difference between Window.eval and eval: Window.eval is just a property called eval in the Window object, a property that points to the Eval function. As with Window.eval2,window.eval3, just one attribute, not the literal eval.

To verify this, I looked at the FireFox script engine source. Where the eval real execution section is defined in the Evalkernel in Jsobj.cpp:

The code is as follows Copy Code

bool
Evalkernel (Jscontext *cx, Uintn argc, Value *VP, Evaltype evaltype, Jsstackframe *caller,
Jsobject *scopeobj)
{
...

/*
* per ES5, indirect eval runs in the global scope. (The eval is specified this
* Way so this compiler can make assumptions about what bindings may or
* May isn't exist in the current frame if it doesn ' eval '.)
*/
UINTN Staticlevel;
if (Evaltype = = Direct_eval) {
Staticlevel = Caller->script ()->staticlevel + 1;

} else {
/* Pretend that we ' re top level. */
Staticlevel = 0;

Js_assert (Scopeobj = = Scopeobj->getglobal ());
Js_assert (Scopeobj->isglobal ());
}

...
}

Obviously, you find that there is a parameter called Evaltype in this function, and it is this parameter that determines whether the eval is running globally. If the Direct_eval,staticlevel is the current context, otherwise the staticlevel=0 is the global.

And we found it in jsinterp.cpp. Call Evalkernel in Direct_eval mode:

  code is as follows copy code

bool
Directeval (Jscontext *cx, jsfunction *evalfun, UInt32 argc, Value *vp)
{
    ...

    jsobject *scopechain =
        getscopechainfast (CX, Caller, Jsop_eval, Jsop_eval_length + jsop_lineno_length);

    if (!scopechain | |!) Evalkernel (CX, ARGC, VP, Direct_eval, Caller, Scopechain))
        return False ;

    CX->REGS->SP = VP + 1;
    return true;
}

The place where the call Directeval is defined is exactly the area of the keyword:

The code is as follows Copy Code

}
End_case (jsop_new)

Begin_case (Jsop_eval)
{
ARGC = GET_ARGC (regs.pc);
VP = regs.sp-(argc + 2);

if (! Isfunctionobject (*VP, &callee))
Goto Call_using_invoke;

Newfun = Callee->getfunctionprivate ();
if (! Isbuiltinevalfunction (Newfun))
Goto Call_using_invoke;

if (! Directeval (CX, Newfun, ARGC, VP))
Goto error;
}
End_case (Jsop_eval)

Begin_case (Jsop_call)
Begin_case (jsop_funapply)
Begin_case (Jsop_funcall)
{

It is clear that eval, like the new one, is treated as a keyword. In other words, only the "eval (...)" appears in the code. These words are passed into the direct_eval, which is executed within the current context.

As you can see, ECMA-262 's eval has the character of a keyword! But it's not really a keyword, because the keyword is not available as an object property name, such as Window.this,window.var is the wrong syntax. But Eval can.

So if you declare a variable in the closure that is called Eval, and point to Window.eval. So what happens?

The code is as follows Copy Code

<script>
function A ()
{
var eval = window.eval;

Eval ("var a=1");
Eval ("var b=1");
}

A ();

Alert (typeof a); Undefined
Alert (typeof B); Undefined
</script>

Why is it undefined? Since this eval is the original eval, it is all executed internally.

But it does not mean that Eval cannot be overwritten:

The code is as follows Copy Code

<script>
eval = alert;

function A ()
{
Eval ("var a=1"); var a=1
Window.eval ("var b=1"); var b=1
}

A ();
</script>

A normal pop-up two dialog box.
It is obvious that in a context where eval keeps pointing to the original function and not being overwritten, it has a feature of the keyword; otherwise, it's a variable called eval. The code in Begin_case (Jsop_eval) {} In Jsinterp.cpp also illustrates

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.