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)
幸運を!