Search code examples
javascriptstringoverriding

Reverting overridden String prototype


I have an overridden String.prototype in my javascript window.

window.String.prototype.toUpperCase = ()=>{return "overridden"}

I have a reference to an iframe window that hasn't been touched, and I want to use it to create a new string without the overridden functions:

console.log(iframe.contentWindow.String("newstring").toUpperCase());
// prints "overridden"

How do I create a new string without the overridden functions?

For overridden Array.prototype using a fresh iframe works but not for String.

console.log(iframe.contentWindow.Array(1,2,3).filter(a=>a));
// that works - prints - [1,2,3]

Note

I know it shouldn't be done. I am asking how it can be fixed in the situation in which another 3rd party library did it.


Solution

  • The problem is that iframe.contentWindow.String("newstring") just returns a string, the same primitive string that String("newstring") or just "newstring" do evaluate to. When accessing a method on that string, the String.prototype from the current realm is used, which has the broken toUpperCase.

    You would need to create an instance to get a string object that inherits from the iframe's String.prototype:

    const stringObj = new iframe.contentWindow.String("newstring");
    console.log(stringObj.toUpperCase());
    

    However, it's easier to just restore the method:

    String.prototype.toUpperCase = iframe.contentWindow.String.prototype.toUpperCase;
    console.log("newstring".toUpperCase());