创建JavaScript数组原型的复位时Array.prototype已被修改? [英] Create a reset of javascript Array prototype when Array.prototype has been modified?

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

问题描述

常规问题::当一个默认的Javascript原型像阵已被修改,黑客入侵,改变和扭曲到不可用的程度,有没有什么方法来创建的实例(或重新实现)原来,未修改的原型?


我的情况:我有一些code,它是在一个的编辑模式失败(可怕的,专有的,封闭源代码......)的内容管理系统,因为JavaScript来实现内容管理系统中的编辑模式的接口黑客的绝对人间地狱了阵列原型。

我的code将在CMS的非编辑模式下工作,但是到那里,它在编辑模式下进行测试。 这是可能的,如果测试的原型已被修改。是否有可能重新实现默认阵列的原型,所以我可以做这样的事情:

  VAR hasArrayBeenTrashed = //基于http://stackoverflow.com/questions/574584/布尔
VAR normalArray.prototype = //基于这个问题的答案
VAR myArray的=!hasArrayBeenTrashed? []:新normalArray;


解决方案

OP的可能已经出来的东西到现在,但对于其他人从谷歌未来在搜索或其它地方,这里有一个函数返回未修改版本中的任何的默认构造函数传递给它:

//注意:下面的双重名称分配是故意的。
//只有当你想使用一个不同的变量名称更改这一部分。
//│││││另外一个在这里需要保持不变,内部参​​考相同。
//↓↓↓↓↓↓↓↓↓↓
VAR复位=功能复位(构造){
    如果(!(复位constructor.name)){
        VAR IFRAME =使用document.createElement('IFRAME');
        iframe.src ='关于:空白;
        document.body.appendChild(IFRAME);
        复位[constructor.name] = iframe.contentWindow [constructor.name]
        document.body.removeChild(IFRAME);
    }返回复位[constructor.name]
}


用法是这样的:

问题

有人做一些愚蠢到默认的原型...

Array.prototype.push =功能(){
    VAR认为这=;
    [] .forEach.call(参数,函数(参数){
        that.splice(Math.round(的Math.random()* that.length),0,参数)
    });返回'Trolololo';
}

...和你的code变成一个破烂摊子。

myarray的无功=新的Array(0,1,2,3);
// - >未定义
    //好吧,我做了一个数组。
myArray的;
// - > [0,1,2,3]
    // 到现在为止还挺好...
myArray.push(4,5);
// - > Trolololo
    // 什么?
myArray的;
// - > [5,0,1,2,4,3]
    // 什么!?

解决方案

所以你把这个函数到混合...

VAR复位=功能复位(构造){
    如果(!(复位constructor.name)){
        VAR IFRAME =使用document.createElement('IFRAME');
        iframe.src ='关于:空白;
        document.body.appendChild(IFRAME);
        复位[constructor.name] = iframe.contentWindow [constructor.name]
        document.body.removeChild(IFRAME);
    }返回复位[constructor.name]
}

...并把它用像这样。

VAR myArray的=新的重置(阵列)(0,1,2,3);
// - >未定义
    //看起来是一样的
myArray的;
// - > [0,1,2,3]
    //看起来还是一样
myArray.push(4,5);
// - > 6
    //嘿,这回什么它应该...
myArray的;
// - > [0,1,2,3,4,5]
    // ......和所有是正确的世界了!

此外,因为每个复位构造缓存第一次它回来了,你可以,如果你想通过直接引用缓存( reset.Array ),而不是通过函数(复位(阵列))之后,每次


祝你好运!

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?


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.

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 http://stackoverflow.com/questions/574584/
var normalArray.prototype = // based on answer to this question 
var myArray = !hasArrayBeenTrashed ? [] : new normalArray;

解决方案

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];
}


Usage goes like this:

The Problem

Somebody does something stupid to a default 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';
}

...and your code becomes a broken mess.

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!?

The Solution

So you throw that function into the mix...

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];
}

...and put it to use like so.

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!

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.


Good luck!

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

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