在javascript中重新定义Array构造函数

时间:2013-03-13 12:38:00

标签: javascript

说我有以下代码:

var secrets;
Array = function() {
  secrets = this;
};

上述示例的作者说代码正在重新定义Array构造函数。首先,我不确定this指的是什么。任何人都可以建议吗?

第二:以下代码是否相同?

var secrets;
function Array() {
  secrets = this;
}

顺便提一下上面的代码来自以下关于Json漏洞的文章:see here

2 个答案:

答案 0 :(得分:5)

在这两个示例中,您将变量Array定义为function,将this分配给secrets。恰好已经存在一个名为Array的全局对象,页面中的其他JS可能会或可能不会用作Constructor来创建数组。如果您弹出控制台并重新将Array指定为其他内容,则可能会从明确依赖Array的代码开始收到错误。但是,字面上使用[]的数组继续正常工作,事实上,他们的__proto__仍然指向Array.prototype。所以:

var arr1 = new Array('a','b','c');
// arr[0] -> 'a'

var arr2 = ['d','e','f'];
// arr[0] -> 'd'

var secrets;
Array = function() { secrets = this; };

var arr3 = new Array('g','h','i'); // nothing wrong here, because Array is a function
// arr3[0] -> undefined
// Array is just a function, you can't make arrays with new Array anymore
// and arr3 is just a function


var arr4 = ['j','k','l'];
// arr4[0] -> 'j'
// making array literals still works

至于this,没什么奇怪的,仍然遵循this的规则。您将某个功能分配给Array这一事实并未改变this的行为方式。所以this指向浏览器中window的全局对象,除非您使用new实例化或使用callapply

两个样本之间的差异是函数表达式和函数声明之间的差异,请参阅:What is the difference between a function expression vs declaration in Javascript?

答案 1 :(得分:1)

是的,两个片段都是等效的。两者都重新定义了数组构造函数,试图拦截它注入的网站使用的所有数组数据,如链接文章中所述。 this的值应该是新构造的数组。

这似乎已被ECMAScript 3所允许,但ECMAScript 5不允许,现在所有现代浏览器都可以使用。因此,本文中描述的漏洞利用应该不再适用。