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

时间:2012-07-17 16:42:10

标签: javascript arrays method-interception

此问题与What are the best practices to follow when declaring an array in Javascript?

有关

假设一个客户端,我们称之为"D. B. Cooper",首先要求以下代码必须在任何其他JavaScript代码之前运行:

Array = function(){
    alert('Mwahahahaha');
};

此外,Cooper要求必须将自定义函数添加到内置的Array对象(而不是被劫持的对象)中。例如,如果Array未被劫持,则可以通过以下方式完成:

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

哪个可以提供:

var myArray = [];
myArray.coolCustomFunction();

但是,这与第一个要求不兼容。那么,你怎么能最好地满足D. B. Cooper的要求?

注意: D.B.甚至写了 a test fiddle 来帮助确保解决方案符合他的要求......真是个男人!


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

3 个答案:

答案 0 :(得分:3)

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

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"

http://jsfiddle.net/yXPJ8/5/

答案 1 :(得分:2)

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

访问它
Object.getPrototypeOf([])

即使Array[].constructor被劫持。 (当Object被劫持时,当然不会起作用,那么它会变得非常复杂)

Brought D.B. down!


如果您想使用变通方法,in FF以下行将始终有效(并且不会被劫持):

[].__proto__.coolCustomFunction = coolCustomFunction;

答案 2 :(得分:1)

是的......你刚才......但是你使用[]创建了数组..如果你使用new Array()它就可以了......

See example here