Is there a way to get the default value of an object in the global scope?
For example, let's say that I need to use Math.round
, but Math.round
has been overwritten with another value. Here's an example of what I'm talking about:
// script1.js (can't be edited)
Math.round = () => null;
Object.freeze(Math); // delete Math.round method and freeze Math object
// script2.js (loads after script1.js)
console.log(Math.round(3.141592)); // should return 3
Is it possible to get the default value that the browser sets (function round() { [native code] }
) after it is overwritten in Javascript?
The only solution I can think of is to use iframes. Each iframe will have it's own newly-created window object, which you can then use in the parent frame (if they're of the same origin).
Math.round = () => null
const frame = document.createElement('iframe')
document.body.appendChild(frame)
Math.round(2.5) // null
frame.contentWindow.Math.round(2.5) // 3
You can even call DOM functions from the iframe against the current page if you supply the right "this" to the function:
// will return your page's body, not the body in the iframe.
// This is because we're telling it to use our document object as "this", instead of the iframe's document.
frame.contentWindow.document.querySelector.call(document, 'body')
In the future, we may get better support for being able to run scripts in their own isolated "realm", where they can have their own separate global enviornment to muck around with. See this upcoming ecmascript proposal to learn more. (at the time of writing, this is currently in stage 2)
Finally, I'll note a couple alternative solutions that may be a better way to go depending on the situation: