当 Array.prototype 被修改时,创建 javascript Array 原型的重置? [英] Create a reset of javascript Array prototype when Array.prototype has been modified?

查看:40
本文介绍了当 Array.prototype 被修改时,创建 javascript Array 原型的重置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

General question: When a default Javascript prototype like Array has been modified, hacked, changed and twisted to the point of being unusable, is there any way to create instances of (or re-implement) the original, un-modified prototype?

我的情况:我有一些代码在(可怕的、专有的、封闭源代码...)内容管理系统的编辑"模式下失败,因为用于内容管理系统编辑"模式的界面从 Array 原型中破解了绝对的地狱.

My case: I've got some code that is failing in the 'edit' mode of a (horrible, proprietary, closed source...) content management system, because the javascript for the interface of the 'edit' mode of the content management system hacks the absolute living hell out of the Array prototype.

我的代码将在 CMS 的非编辑模式下工作,但是,为了实现这一目标,它已经在编辑"模式下进行了测试.可以测试原型是否已修改.是否可以重新实现默认的 Array 原型,以便我可以执行以下操作:

My code will work in the non-edit mode of the CMS, but, to get there, it has be tested in the 'edit' mode. It's possible to test if a prototype has been modified. Is it possible to re-implement the default Array prototype so I could do something like this:

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 搜索或其他任何地方进入的任何其他人,这里有一个 返回未修改版本的函数传递给它的任何默认构造函数:

OP's probably already figured something out by now, but for anyone else coming in from a Google search or wherever, here's a function that returns the unmodified version of any default constructor passed to it:

// 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)).

Also, because each reset constructor is cached the first time it's returned, you can save a character if you want to by referencing the cache directly (reset.Array) instead of through the function (reset(Array)) every time after that.

祝你好运!

这篇关于当 Array.prototype 被修改时,创建 javascript Array 原型的重置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆