In short - YES
With is special, it does dynamic binding. It creates confusing bugs which is why with
statements do not run in strict mode.
However no one said we can't have a little fun. We can't change the closure variables the function has, however - we can exploit JavaScript's highly dynamic nature to read the function's source code and generate a new binding. It's not core language or generic, but for the case you asked it's certainly doable.
Here is a sample for the very basic case you asked (no nested closures, no parameters etc) . While you can't alter the closure, you can declare a new function that runs the same code of the other one. Let me make one thing very clear - this is a dirty hack here ;)
var scope = {foo: 'bar'},
foo = 'baz';
var func = function func() {
return foo;
}
// here, `foo` is closed over by the outer foo and it is 'baz'
document.body.innerHTML += " " + func(); // foo is still 'baz'
// foo is bar, since it's a different function here:
document.body.innerHTML += " " + withFunc({foo:"bar"},func);
function withFunc(obj, func) {
//declare a new function
return new Function("obj", // with a parameter obj
"with(obj){\n " + // do `with` on that parameter
"return "+func+"()\n}")(obj); // invoke and return original function
}
http://jsfiddle.net/42YX4/