This is a hypothetical question, it really doesn't have a practical use, but...
Let's say you were to do:
document.open = null;
How would one restore document.open to its original functionality, is this possible (without user-made temporary storage)? Is document.open stored in another location under a less known name? Thankyou! :)
This is a hypothetical question, it really doesn't have a practical use, but...
Let's say you were to do:
document.open = null;
How would one restore document.open to its original functionality, is this possible (without user-made temporary storage)? Is document.open stored in another location under a less known name? Thankyou! :)
Share Improve this question asked Jul 9, 2012 at 22:35 Georges Oates LarsenGeorges Oates Larsen 7,10212 gold badges52 silver badges68 bronze badges 1- FYI, it IS practical in my case because I was trying to run some native code on a webpage that has already override that method. it is pretty frustrating until I saw your question – Phạm Huy Phát Commented Aug 21, 2024 at 5:05
4 Answers
Reset to default 10Overwriting document.open
creates a variable/function named open
directly on the document
object. However, the original function was not on the object itself but its prototype - so you can indeed restore it.
The open
function is from HTMLDocument.prototype
so you can access it using HTMLDocument.prototype.open
.
To call it directly, use .call()
to specify the object to use it on:
HTMLDocument.prototype.open.call(document, ...);
You can also restore document.open
it by simply assigning it:
document.open = HTMLDocument.prototype.open;
However, remember that HTMLDocument
and thus document
are host objects and it's usually a good idea not to mess with them - especially in IE things are likely to go haywire if you do so.
delete document.open;
It's not intuitive, but using the delete keyword on a customized function will restore the original function, at least as long as the prototype hasn't been overwritten.
Example:
> console.log
function log() { [native code] }
> console.log = function() { }
function () { }
> console.log("Hello world");
undefined
> delete console.log;
true
> console.log("Hello world");
Hello world
Works the same way with document.open and other built-in functions.
var temp = document.open;
document.open = null;
and then you restore the original function with
document.open = temp;
To retrieve methods even when the prototype has been changed, or when they're not derived from any prototype, like e.g. window.alert()
, you can use another browsing context to retrieve the original method, in other words, either an <iframe>
or a Window from open()
should be clean. Then you can get the unmodified version from there, and rebind it to your own instance.
However this still has its limitations. Whatever bricked your page must have forgotten to also brick ways to create an <iframe>
or an <object>
HTML element, or to call open()
. You must also be in a context where you can access other browsing contexts (i.e. you're not in a sandboxed context).
window.alert = () => console.log("bricked");
alert("foo"); // logs "bricked"
// Assumes document.createElement("iframe") works
// If it doesn't, one can try other ways to create that element, like `innerHTML` etc.
const frame = document.createElement("iframe");
document.body.append(frame);
window.alert = frame.contentWindow.alert.bind(window);
frame.remove();
alert("bar"); // works
Unfortunately, StackSnippet's iframes are such a sandboxed context where this wouldn't work, so I have to outsource the demo on jsfiddle instead.