Actually eval creates variables or modifies variables in scope where it is defined, no matter if you use val or not. Or in other words, by default it doesn't have it's own scope.
So when you do this
eval("var outer = 0;");
console.log(outer); //0
you create variable in outer scope. Surprisingly, this works the same way in chrome too - and it doesn't matter if window.onload is used or not.
To make eval has it's own scope you must do the following:
eval("'use strict'; var outer = 0;");
console.log(outer); //Uncaught ReferenceError: outer is not defined
Now there is a separate scope for eval.
With 'use strict' in eval your code will work in chrome and won't allow to override variables outside eval.
eval("'use strict'; var outer = 0; function test() {'use strict'; outer = 1; } test(); alert('ok');");
So this part answers how can you avoid error.
The second part that I am very intersted in but couldn't find an answer by myself.
The question is following, why your code throws an error in chrome while this works in chrome(which means the global variable is created):
window.onload = function() {
eval("var outer = 0; function test(){console.log(outer); } test();");
}
And also why it happens only with window.onload
.