7

这个问题与在 Javascript 中声明数组时要遵循的最佳实践是什么有关?


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

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

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

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

这将负担得起:

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

但是,这与第一个要求不兼容。因此,您如何才能最好地满足 DB Cooper 的这两个要求?

注意: DB 甚至写了一个测试小提琴来帮助确保解决方案满足他的要求……真是个家伙!


更新: 对于那些喜欢挑战的人:请尝试找到一个不可劫持的跨浏览器解决方案来解决这个问题。例如,这里有一个更被劫持的测试用例(感谢重新格式化这个 Bergi),它劫持了 Array、Object、Array.prototype.constructor 和 Object.prototype.constructor。到目前为止,看起来可能有一个特定于浏览器的解决方案(参见Bergi 对他的回答的评论,如果你找到在 FF 中劫持它的方法,请告诉我们),但目前尚不清楚是否存在一个跨浏览器的解决方案。

4

3 回答 3

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/

于 2012-07-17T16:54:57.507 回答
3

无论您的Array函数/构造函数是什么,数组的文字语法将始终生成“真实”数组,并将它们的 [[prototype]] 设置为本机数组原型对象(曾经,这是一个安全漏洞)。因此,您始终可以使用

Object.getPrototypeOf([])

即使Array或被[].constructor劫持。(被劫持当然不行Object,那就很复杂了)

把 DB 打倒了!


如果您想使用解决方法,在 FF中,以下行将始终有效(并且不可劫持):

[].__proto__.coolCustomFunction = coolCustomFunction;
于 2012-07-17T17:31:08.847 回答
1

是的......你刚刚做了......但是你使用[]..创建了数组,如果你使用new Array()它工作正常......

在此处查看示例

于 2012-07-17T16:44:49.833 回答