OP 现在可能已经想通了,但是对于从 Google 搜索或其他任何地方进入的任何其他人,这里有一个函数返回传递给它的任何默认构造函数的未修改版本:
// Note: the double name assignment below is intentional.
// Only change this part if you want to use a different variable name.
// │││││ The other one here needs to stay the same for internal reference.
// ↓↓↓↓↓ ↓↓↓↓↓
var reset = function reset(constructor) {
if (!(constructor.name in reset)) {
var iframe = document.createElement('iframe');
iframe.src = 'about:blank';
document.body.appendChild(iframe);
reset[constructor.name] = iframe.contentWindow[constructor.name];
document.body.removeChild(iframe);
} return reset[constructor.name];
}
用法如下:
问题
有人对默认原型做了一些愚蠢的事情......
Array.prototype.push = function () {
var that = this;
[].forEach.call(arguments, function (argument) {
that.splice(Math.round(Math.random()*that.length), 0, argument)
}); return 'Trolololo';
}
...你的代码变得一团糟。
var myArray = new Array(0, 1, 2, 3);
//-> undefined
// Ok, I made an array.
myArray;
//-> [0, 1, 2, 3]
// So far so good...
myArray.push(4, 5);
//-> "Trolololo"
// What?
myArray;
//-> [5, 0, 1, 2, 4, 3]
// WHAT!?
解决方案
所以你把那个函数扔进去……
var reset = function reset(constructor) {
if (!(constructor.name in reset)) {
var iframe = document.createElement('iframe');
iframe.src = 'about:blank';
document.body.appendChild(iframe);
reset[constructor.name] = iframe.contentWindow[constructor.name];
document.body.removeChild(iframe);
} return reset[constructor.name];
}
...并像这样使用它。
var myArray = new reset(Array)(0, 1, 2, 3);
//-> undefined
// Looks the same
myArray;
//-> [0, 1, 2, 3]
// Still looks the same
myArray.push(4, 5);
//-> 6
// Hey, it returned what it's supposed to...
myArray;
//-> [0, 1, 2, 3, 4, 5]
// ...and all's right with the world again!
此外,因为每个重置构造函数在第一次返回时都会被缓存,所以如果您愿意,可以通过直接引用缓存 ( reset.Array
) 而不是reset(Array)
每次都通过函数 ( )来保存字符。
祝你好运!