IE9中JavaScript中针对不同上下文原型的Bug?
在IE9中,执行以下操作:IE9中JavaScript中针对不同上下文原型的Bug?,javascript,popup,internet-explorer-9,prototype-programming,Javascript,Popup,Internet Explorer 9,Prototype Programming,在IE9中,执行以下操作: Array.prototype.$$isArray = true; var popup = window.open( .... ); // later var x = ['test']; alert( x[0] ); // Shows "test" alert( x.$$isArray ); // Shows "true" 在弹出的HTML中,执行以下操作: function test( x ) { alert( x[0] ); //
Array.prototype.$$isArray = true;
var popup = window.open( .... );
// later
var x = ['test'];
alert( x[0] ); // Shows "test"
alert( x.$$isArray ); // Shows "true"
在弹出的HTML中,执行以下操作:
function test( x ) {
alert( x[0] ); // Shows "test"
alert( x.$$isArray ); // Shows "undefined"
)
为什么结果不同?这是IE中的一个bug吗?不,它不是bug(至少不是在浏览器中),而且不仅仅是IE
浏览器显示的每个文档都有自己的全局环境,包括基本对象的原型。他们都是一片空白。一个文档中的数组
构造函数与另一个文档中的数组
构造函数不同,并且这些构造函数不共享一个公共原型
属性;环境已断开连接。这就是为什么instanceof
在多文档web应用程序中不能很好地工作的原因
考虑这个例子():
它打开一个弹出窗口,然后从中检索数组。但是我们收到的数组是由一个与窗口中的对象不同的数组
对象构建的,因此没有我们添加到数组。原型
。然后,它创建一个包含这些添加内容的数组实例,并将其传递给弹出窗口,弹出窗口可以正确查看添加内容(因为对象继续引用其原始原型):
主窗口中的输出:
将属性添加到Array.prototype
本地测试属性,
[]。\uuufoo=bar
打开弹出窗口
正在等待窗口加载。。。
窗口已加载,正在从中获取数组
a
内容:1、2、3
a.。\uuufoo=未定义
数组的实例
?假的
wnd.Array===Array
?假的
创建b
b.\uuufoo=bar
将b
传递到弹出窗口,在那里查找结果
…并在弹出窗口中:
我是弹出窗口。
收到的x
:3,4,5
x.\uuufoo=bar
您将在IE(我专门测试了IE9,但它可以在IE7上工作,我相信其他浏览器也可以)和其他浏览器上看到该输出
两个不同窗口中的环境可以相互通信,但它们没有共享的全局文件;父窗口中的Array.prototype
不会以任何方式被子窗口继承
您在评论中说,当您将数组从主窗口传递到子窗口时,添加内容“消失”。(代码中没有任何内容显示您这样做。)从上面可以看出,事实上,对象保持了与原型的正确关系,并且确实显示了添加内容,因此我怀疑(抱歉)这只是代码中的一个错误。在弹出窗口中执行的脚本具有不同的上下文,因此如果在弹出窗口中尝试此操作:
Array === window.top.Array // false
看起来你遇到了IEisArray()
bug,并在某个地方有点交叉。我已经更新了我的,请随意看看这是否解决了您的问题。我知道这些窗口使用不同的原型,但我在源原型上设置了该属性。甚至内置调试器也在其检查器中显示了附加属性…@Steffen:没有“源原型”(至少,没有可公开访问的原型;可能有一个隐藏在JavaScript引擎的实现细节中)。您正在写入的Array.prototype
仅用于该窗口。如果您在调试器中看到新属性,我只能假设您正在查看分配属性的窗口的数组.prototype
,而不是弹出窗口。每个对象都链接到某个原型。即使在创建对象之后更改原型,也会更改对象的(视图)<代码>变量x=[];Array.prototype.y=1;x、 z=2;警报(x.y+','+x.z)代码>警报1,2
。当我将x
传递到另一个窗口,并且该窗口调用相同的警报时,它将显示未定义,2
。那没有任何意义。我同意,如果我更改新窗口的数组原型,这是不同的,因为这与变量x无关。@Steffen:是的,我理解原型继承是如何工作的。您从未说过要将实例从父窗口传递给子窗口,您的代码也没有显示要这样做。但是它应该可以工作,并且实例应该保持它与原型的关联,因此保留您添加到原型中的任何属性。我已经更新了我的示例,以显示它在IE9和其他浏览器上的工作情况。抱歉,我认为你的代码中有一个bug。如果您使用所有代码创建一个完整的、自包含的测试用例,我希望我们能够解释出哪里出了问题。
Array === window.top.Array // false