你能给被劫持的JavaScript数组添加一个函数吗?

你能给被劫持的JavaScript数组添加一个函数吗?,javascript,arrays,method-interception,Javascript,Arrays,Method Interception,这个问题与 假设一个客户机(让我们调用它们)有一个第一个要求,即以下代码必须在任何其他JavaScript代码之前运行: Array = function(){ alert('Mwahahahaha'); }; 此外,Cooper要求必须将自定义函数添加到内置的数组对象(而不是被劫持的对象)。例如,如果Array已取消链接,则可通过以下方式完成: Array.prototype.coolCustomFunction = function(){ alert('I have '

这个问题与


假设一个客户机(让我们调用它们)有一个第一个要求,即以下代码必须在任何其他JavaScript代码之前运行:

Array = function(){
    alert('Mwahahahaha');
};
此外,Cooper要求必须将自定义函数添加到内置的
数组
对象(而不是被劫持的对象)。例如,如果
Array
已取消链接,则可通过以下方式完成:

Array.prototype.coolCustomFunction = function(){
    alert('I have ' + this.length + ' elements!  Cool!');
};
这将提供:

var myArray = [];
myArray.coolCustomFunction();
但是,这与第一个要求不兼容。因此,如何才能最好地满足D.B.Cooper的两个要求

注意:D.B.甚至写了来帮助确保解决方案满足他的要求……真是个家伙


更新:
对于那些喜欢挑战的人:请尝试找到解决此问题的跨浏览器解决方案。例如,一个更被劫持的测试用例(感谢您重新格式化这个Bergi)劫持了Array、Object、Array.prototype.constructor和Object.prototype.constructor。到目前为止,似乎有一个特定于浏览器的解决方案(请参阅,如果您在FF中找到劫持它的方法,请告诉我们),但目前还不清楚是否有跨浏览器的解决方案。

是。。。你只是。。。但是您使用
[]
创建了阵列。。如果您使用
new Array()
它可以正常工作


由于
数组
不一定等于
[].constructor
,您可以使用
[].constructor
引用原始数组函数,因为它是硬连线的,
数组=函数(){}
不会改变它

Array = function () { alert("foo")};

// this will always point to the original Array
[].constructor.prototype.foo = "bar";

var myArray = [0, 1];
alert(myArray.foo) // alerts "bar"

无论您的
数组
函数/构造函数是什么,数组的文字语法总是会生成“真实”数组,并将其[[prototype]]设置为本机数组原型对象(一次,这一次)。因此,您始终可以使用

Object.getPrototypeOf([])
即使
数组
[]构造函数
被劫持。(当
对象被劫持时,它当然不起作用,然后它变得非常复杂)

()


如果要使用变通方法,以下行将始终有效(并且不可劫持):


很抱歉,这不符合测试用例。您不允许编辑它。@Briguy37那么它不能-您不能覆盖
[]
函数-这指向一个内部构造函数,很可能就是这种情况。但是,如果在劫持前修改
数组的原型以添加函数,则可以在使用
[]
创建的对象上使用该函数。因此,我想知道在Array被劫持后是否有办法做到这一点。这个问题的格式应该是SON上新海报所需的学习材料。将需求文档发送回D.B.Cooper,并坚持每个需求的用例。:)@昆汀:如果你能找到他,那将是一个很好的选择:)你的第一个解决方案让D.B.很高兴:)(第二个将违反他的第一个要求)好的,错过了“在任何其他之前”的部分<代码>[].constructor=function(){}仍然只引用该实例的构造函数。对
[].constructor
的后续调用将具有完整的引用,因为它是为每个实例创建的新引用。但是,您可以尝试覆盖
构造函数.prototype
,因为它受到保护(除非JS引擎被破坏),所以它不会起任何作用。@Bergi Nice catch-很有趣,即使
Array.prototype.constructor
将指向另一个创建数组的函数仍然有效。如果删除了对原型构造函数的所有引用,那么当然,如果不重新加载页面或打开新窗口并从中获取它,就无法将其取回<代码>var-win=window.open();Array.prototype.constructor=win.Array.prototype.constructor@TorstenWalter:虽然我不能让它工作。你能演示一下吗?很有趣!我决定尝试劫持数组对象的构造函数:
[].constructor.prototype.constructor=..
,这导致Torsten的解决方案失败。然后,我劫持了这个对象,这导致您的解决方案失败,但它可以使用
({}).constructor
。然后我劫持了对象的构造函数:
({}).constructor.prototype.constructor=…
,这导致了所有操作都失败。在这一点上,我被卡住了,所以我还没有找到一个不可劫持的解决方案:)这里有一个更新的提琴:这正是我的思路:-)但是,我必须更具可读性。现在,你只能在FF中使用非标准的
\uuuuu proto\uuuuuuu
(我认为是不可隐藏的)非常好,我也看不到在FF中劫持它的方法!我仍然对@Torsten从新窗口对象或其他方法获取构造函数的建议是否会导致跨浏览器不可劫持的解决方案感兴趣。实际上,
\uuuuu proto\uu
只是一个getter/setter属性,而不是内置属性。您可以
删除Object.prototype.\uuu proto\uu
[].__proto__.coolCustomFunction = coolCustomFunction;