2

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?

5
  • If you freeze it before deletion, it will retain the original value if thats what you are asking. Commented Dec 12, 2020 at 7:01
  • Yes, but I need to be able to access it after deletion Commented Dec 12, 2020 at 7:05
  • Not sure what you mean by access, but if you do freeze before you reassign the function, then it will retain its original value and you will be able to console.log 3 and use the function like you never edited it. Commented Dec 12, 2020 at 7:07
  • @FarazShaikh I've updated the question. Basically, the freezing is done in a script that cannot be edited and always loads before where I need to access the property. Commented Dec 12, 2020 at 7:09
  • You can use an iframe and get its Math object then delete the iframe right after. I would post that solution here but it does not allow me access iframes because of a security exception. Commented Dec 12, 2020 at 7:57

1 Answer 1

2

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:

  • If you have full control over the page, then you should be able to save off global variables before you load these naughty scripts. Alternatively, you could load the script in an iframe to isolate it's bad behavior.
  • If possible, it might be better just to let the globals get modified. Scripts really shouldn't be touching them, and if they are, it's probably because they're trying to pollyfill some missing features. Its rare that a script is actually making breaking changes to global function - but if they are, it might be worth it to file a bug report with the script author to fix this behavior.
Sign up to request clarification or add additional context in comments.

1 Comment

+1 for the last part. Either you trust the script author not to mess with your page, or you shouldn't be running their script on your page (without isolation) in the first place.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.