Wednesday, October 08, 2008

Understanding eval scope. Spoiler: It's unreliable!

Today, I ran some tests to help me understand the scope in which an eval runs. Turns out, like so many things in the browser world, it's very unpredictable and exhibit different behaviors in different browsers.

Let's start with the following snippet of code. I've added comments to demarcate areas in the code, which I will be changing with each iteration.


var foo = 123;
var bar = {
changeFoo: function() {
// We'll keep changing the following snippet
alert(this);
eval("var foo = 456");
// Changing snippet ends
}
};

bar.changeFoo();
alert(foo);

A little explanation of the code above. foo is a variable in the global scope, and it's value is set to 123. An object bar is created with a single method changeFoo which does an eval. The eval creates a local variable (thanks to the var) foo, and sets it's value to 456. bar.changeFoo is called, and the value of the global foo is alerted.

The aim is to test the scope in which eval runs. If eval is in the global scope, the global variable foo should change it's value. If eval is in the local scope, the global foo should be unaffected. Then there are various things we can do inside the changeFoo method which should keep altering the scope of this, so we are also alerting this to see what happens.

The findings are listed below:

 Changed snippetInternet ExplorerSafari 3.xFirefoxGoogle ChromeSafari Nightlies
  foothisfoothisfoothisfoothisfoothis
1
alert(this);
eval("var foo=456");
123object123object123object123object123object
2
alert(this);
window.eval("var foo=456");
123object123object456object123object456object
3
alert(this);
this.eval("var foo=456");
errorobjecterrorobjecterrorobjecterrorobjecterrorobject
4
alert(this);
eval("var foo=456", window);
123object123object456object123object123object
5
(function() {
alert(this);
eval("var foo=456");
})();
123object123window123window123object123window
6
(function() {
alert(this);
window.eval("var foo=456");
})();
123object123window456window123object456window
7
with(window) {
alert(this);
eval("var foo=456");
}
456object456object456object456object456object
8
with(window) {
alert(this);
window.eval("var foo=456");
}
456object456object456object456object456object

What I think of these results:

  • I don't know what Firefox is doing in case 2, and for some reason Safari Nightlies seem to be following it. Maybe it's just beyond my understanding, but case 2 is not supposed to be different from case 1. Why does case 2 operate in global scope? If window.eval is different from eval, case 3 shouldn't all have given errors. Someone please help me understand that $hit.
  • Case 4 makes sense, but that's a non-standard behavior in Firefox. Understandable that no one else exhibits it.
  • IE baffles me in case 5, and Chrome seems to ape it. In this scenario, the anonymous function is supposed to have the global scope - so, in this case, this should point to the window. WTF is happening here!
  • Consistent with case 2 above, Firefox and Safari Nightlies continue to display weird behavior in case 6. For some reason, in these two cases, the eval operates in the global scope.
  • Now, I have no idea why, but only cases 8 and 9 seem to really work at all. This is despite Doug Crockford going on and on about not using with constructs. It's also despite being beyond (my) understanding about why the with should make any difference to the eval, since eval is part of the window object.

All in all, if you are going to be evaling JavaScript (not JSON), and you want the eval'd code to run in the global scope, you should use the with block around the JavaScript snippet. Or else, you can lose a lot of hair handling cross-browser issues.

Hope you don't lose as much hair as me.

222 comments:

«Oldest   ‹Older   201 – 222 of 222
KellyP said...

I've also encountered inconsistencies with eval's scope behavior across different browsers. It can be quite frustrating when relying on it for dynamic code execution.

Cable tray systems

Lesley said...

I have to say, I really admire your commitment to delivering high-quality content consistently. It’s not easy, but you make it look effortless. Roofing Pros of Burnaby

khaye530 said...

Exploring the scope of `eval` reveals just how inconsistent and unpredictable it can be across different browsers. Depending on the context, `eval` might interact with global or local variables, leading to varying outcomes. This makes it unreliable for consistent behavior, and it's a reminder to be cautious when using `eval` in your code. Far & Wide Land Surveying

Anonymous said...

Exploring the scope of eval reveals how unpredictable and inconsistent it can be across different browsers. Despite expectations, eval behaves differently depending on the context, which can make debugging tricky. It's a reminder that relying on eval for scope-sensitive operations can lead to unreliable results. Top Peak Welding

Unknown said...

This is an interesting exploration of how eval behaves in different scopes, particularly in the context of browsers. The key point to keep in mind is that eval behaves differently depending on whether it's being used in strict mode, the environment it’s being called from, and the specific browser's JavaScript engine. reviews

KellyP said...

That's interesting! It seems like understanding the scope of eval in different browsers can be quite complex. I'm curious to know what specific behaviors you observed across different browsers. Did you encounter any unexpected results or limitations?

Security fence

Anonymous said...

The vehicle was luxurious and spotless, and our chauffeur was professional and knowledgeable about the region. limo naperville

Mary said...

My friend, Mary explains this to me very clearly. Thanks to you!

Anonymous said...

The results highlight how tricky and inconsistent `eval` can be across different browsers, especially with regards to scope. It's surprising how Firefox and Safari Nightlies treat `window.eval` differently in case 2, and the behavior of anonymous functions in case 5 is puzzling. The key takeaway is that when dealing with `eval`, using a `with` block seems to give more predictable results across browsers, though it's often discouraged for other reasons. Cross-browser testing is definitely crucial to avoid unexpected issues. Insight Property Appraisals

Unknown said...

This is interesting! https://www.themyndclinic.com/

Lawrenceville Concrete said...

The blog post on Rakesh Pai's website likely dives into the intricacies of the eval() function in programming, particularly its scope and how it behaves in different contexts. It may explain common pitfalls, how eval interacts with variables, and best practices for avoiding potential security risks. Concrete Patio Lawrenceville

Anonymous said...

this contains global info that is useful in every aspect. cleaning services

chavesarlene4 said...
This comment has been removed by the author.
David said...

Eval scope is so confusing! https://www.deckbuildersaskatoon.com/

Unknown said...

Your experiment with eval scope illustrates some classic pitfalls of using eval in JavaScript, especially when it comes to understanding scope in different browsers. Let’s break down what’s going on here and how eval behaves in various scoping scenarios. www.bhi-gc.com/

Vince said...

We always anticipate and love your great articles! Keep them coming! www.concretemilton.com

Goodyear Concrete said...

This blog post by Rakesh Pai dives into the complexities of the eval function's scope in JavaScript, explaining how it behaves differently in global and local contexts. It clarifies why eval can lead to unpredictable behavior and potential security risks, suggesting alternatives for safer code practices. Find out more about Concrete Contractor Goodyear.

Gil said...

I savor, result in I discovered exactly what I used to be looking for.

princegeorgecardetailing.com/car-paint-restoration

Anonymous said...

This is such a fascinating look into the quirks of `eval` scope across different browsers! It really makes you wonder how many other subtle, browser-specific behaviors might be lurking beneath the surface in JavaScript, waiting to catch developers off guard. top-quality car roof lining services in Sydney

Darlene May said...

Very fantastic article. As i only just stumbled upon your current blog site and even preferred expressing we need very enjoyed studying your own website blogposts. Cleaning Services Victoria BC

Dhie said...

Your blog always brightens my day. Keep it light and insightful! www.edmontonfurnacecare.com

BlanchTDemello said...

Thanks for sharing this amazing detail here and when I read about Perth Drain Cleaning Experts I found the best services that are bringing the right results to us.

«Oldest ‹Older   201 – 222 of 222   Newer› Newest»

ShareThis