gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 02:18:33 24 4
gpt4 key购买 nike

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


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

我的代码将在 CMS 的非编辑模式下工作,但是,为了达到目的,它已经在“编辑”模式下进行了测试。 It's possible to test if a prototype has been modified .是否可以重新实现默认的 Array 原型(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/13990187/

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