gpt4 book ai didi

javascript - 当 Array.prototype 被修改时,创建 javascript Array 原型(prototype)的重置?

转载 作者:行者123 更新时间:2023-11-28 03:03:14 25 4
gpt4 key购买 nike

一般问题:当像 Array 这样的默认 Javascript 原型(prototype)被修改、破解、更改和扭曲到无法使用的程度时,是否有任何方法可以创建(或重新实现)实例原始的、未经修改的原型(prototype)?

<小时/>

我的情况:我有一些代码在(可怕的、专有的、闭源的……)内容管理系统的“编辑”模式下失败,因为内容管理系统“编辑”模式的界面从 Array 原型(prototype)中破解了绝对的活生生的 hell 。

我的代码将在 CMS 的非编辑模式下工作,但是,为了实现这一目标,它已经在“编辑”模式下进行了测试。 It's possible to test if a prototype has been modified 。是否可以重新实现默认的数组原型(prototype),这样我就可以做这样的事情:

var hasArrayBeenTrashed = // boolean based on https://stackoverflow.com/questions/574584/
var normalArray.prototype = // based on answer to this question
var myArray = !hasArrayBeenTrashed ? [] : new normalArray;

最佳答案

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];
}
<小时/>

用法如下:

问题

有人对默认原型(prototype)做了一些愚蠢的事情...

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))。

<小时/>

祝你好运!

关于javascript - 当 Array.prototype 被修改时,创建 javascript Array 原型(prototype)的重置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60809479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com