alert;//注释后再次在ie6 ie7 ie8中测试下 var hijack = window.alert; window.alert = function(){ hijack('hijack'); }; alert('origin');
window.alert = null; alert = function(x){document.write(x)}; alert('franky'); //顺利在文档流中加入了 'franky' 并输出到页面.
chrome下执行一下代码 ... Object.prototype['0'] = 'franky'; function f(a){ alert(a); arguments; //如果注释掉arguments调用.则 alert(a)的结果将完全不同. //eval(''); } f();
相关解释:
回头看看chrome干的好事..明显 eval 和arguments 把其对arguments这个对象的某些保护机制给干掉了....
最初,我是这样想的.但仔细想想 不大对劲... arguments;或 eval('') 是放到alert后面也生效的...那么问题应该出在词法分析期.而不是执行期,那么我们就可以推断出,chrome 在分析一个函数主体上下文的时候,会看你是不是有 arguments或eval 如果有 则给这个函数arguments 对象,反之则没有.这本质上 是一种优化. 也就是说chrome程序员,压根就没有给arguments任何保护机制.阻止其访问Object.prototype.
证明这一推论的 论据并不是很充分.但是我还是尝试给出2个...
如果eval 也会触发这个bug .那么我们是不是可以考虑为 . eval 具备一个隶属当前执行上下文环境的(作用于当前作用域),独特的执行上下文环境. 他内部一但出现arguments.则就是当前函数的arguments. 所以chrome不得不在 eval出现时, 也派发给当前函数对象 arguments对象.从而出现了这个bug..
因为 不仅仅eval,new Fcunction(),window.eval('') 也都具备动态执行语句的特点..而区别则在于 作用域.即 除了 eval(''),其他两种方法 无法访问到当前函数的arguments.
open;//按照前面的理解.此处, global.open 会被赋予 window.open
eval('var open');
//按照ES3,5的规范. 这样做应该没有任何意义. 因为global 作为variable object 已经具备一个名为 open的属性. 所以此处应该忽略.
//但实际结果是. open 被赋予了 undefined 这种行为.实在让人无语. 可以说 IE 对 window global的绑定关系已经足够奇葩
//但是对global作为variable object 时.属性为一个宿主方法时的行为则更奇葩...
//所以 如果我们在中间插入eval('var alert'); 又会使alert恢复为原始状态.... 同时,干掉window.alert