I have a script which runs in a site that I cannot count on its window.Array
object to not have been overridden. (It might have been changed by another script that was loaded before).
I create a new iframe and I would like to set the window.Array
object back to the native Array prototype
// let's assume Array.prototype.filter function was changed by another script
Array.prototype.filter = ()=>{return "haha!"}
console.log('test overridden: ', new Array(1,2,3).filter(x=>x));
console.log('test overridden literal:', [1,2,3].filter(x=>x));
// prints test overridden: haha
// prints test overridden literal: haha
// get new window with native code from iframe
var iframe = null;
(iframe = document.createElement('iframe')).name = 'native_function';
document.body.appendChild(iframe);
var native = window.frames['native_function'];
// here I am trying to set my broken Array to a new fresh copy
Object.setPrototypeOf(Array, native.Array.prototype);
console.log('test restored filter: ', new Array(1,2,3).filter(x=>x));
console.log('test restored literal array filter', [1,2,3].filter(x=>x));
// prints test restored filter: haha
// prints test restored literal array filter: haha
// It didn't work.
How can I restore my window.Array to the native.window.Array ?
Note I want to restore the entire Array object to the original Array in the iframe window. Not only the filter function which I just used as as example.
I want to restore the entire Array object to the original Array in the iframe window
You cannot overwrite the builtin array prototype that's used when creating arrays from literals, so instead you need to overwrite the methods on that one.
const iframe = document.body.appendChild(document.createElement("iframe"));
const iframeArray = iframe.contentWindow.Array;
document.body.removeChild(iframe);
const nativeArrayProto = Object.getPrototypeOf([]);
for (const p of ["constructor", "filter", "map", "slice", /* … */])
nativeArrayProto[p] = iframeArray.prototype[p];
Array = nativeArrayProto.constructor;
Array.prototype = nativeArrayProto;