Ответ 1
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 supposed to...
myArray;
//-> [0, 1, 2, 3, 4, 5]
// ...and all right with the world again!
Кроме того, поскольку каждый конструктор reset кэшируется при первом его возврате, вы можете сохранить символ, если хотите, напрямую ссылаясь на кеш (reset.Array
), а не через функцию (reset(Array)
) каждый раз после этого.
Удачи!