在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] ); // Shows "test"
alert( x.$$isArray ); // Shows "undefined"
)
为什么结果不同?这是IE中的错误吗?
答案 0 :(得分:1)
不,这不是一个错误(至少不是在浏览器中),而且它不仅仅是IE。
浏览器显示的每个文档都有自己的全局环境,包括基本对象的原型。他们每个人都是空白。一个文档中的Array
构造函数与另一个文档中的Array
构造函数不同,并且这些构造函数不共享公共prototype
属性;环境断开了。这就是instanceof
在多文档Web应用程序中无法正常工作的原因。
考虑这个例子(live copy):
window.onload = function() {
document.getElementById('theButton').onclick = function() {
var wnd, start;
display("Adding property to <code>Array.prototype</code>");
Array.prototype.__foo = "bar";
display("Testing property locally, <code>[].__foo = " +
[].__foo +
"</code>");
display("Opening pop-up window");
wnd = window.open("http://jsbin.com/omopaw/3");
display("Waiting for window to load...");
start = new Date().getTime();
checkWindowLoad();
function checkWindowLoad() {
var a, b;
if (typeof wnd.getArray === "undefined") {
if (new Date().getTime() - start > 10000) {
display("Error, 10 seconds and the window hasn't loaded");
}
else {
setTimeout(checkWindowLoad, 10);
}
return;
}
display("Window loaded, getting array from it");
a = wnd.getArray();
display("<code>a</code> contents: " + a.join(", "));
display("<code>a.__foo = " + a.__foo + "</code>");
display("<code>a instanceof Array</code>? " +
(a instanceof Array));
display("<code>wnd.Array === Array</code>? " +
(wnd.Array === Array));
display("Creating <code>b</code>");
b = [3, 4, 5];
display("<code>b.__foo = " + b.__foo + "</code>");
display("Passing <code>b</code> to the popup, look there for the result.");
wnd.callback(b);
}
};
function display(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
};
打开一个弹出窗口,然后从中检索一个数组。但是我们收到的数组是由不同的 Array
对象构建的,而不是我们窗口中的对象,因此我们没有添加我们的 { {1}}。然后它创建一个 具有这些添加项的数组实例,并将其传递给弹出窗口,该弹出窗口正确地看到了添加内容(因为对象继续引用其原始原型):
主窗口中的输出:
将属性添加到
Array.prototype
在本地测试属性,Array.prototype
打开弹出窗口
等待窗口加载......
窗口加载,从中获取数组
[].__foo = bar
内容:1,2,3
a
a.__foo = undefined
?假
a instanceof Array
?假
创建wnd.Array === Array
b
将b.__foo = bar
传递给弹出窗口,查看结果。
...并在弹出窗口中显示:
我是弹出窗口。
收到b
:3,4,5
x
你会在IE上看到输出(我专门测试IE9,但它适用于IE7,我也确定其他人也适用)和其他浏览器。
两个不同窗口中的环境可以相互通信,但它们没有共享的全局变量;父窗口中的x.__foo = bar
不会以任何方式由子窗口继承。
您在评论中说过,当您将数组从主窗口传递到子窗口时,添加内容会“消失”。 (你的代码中没有任何东西显示你这样做。)我们可以从上面看到,实际上,对象保持与其原型的关系正确并且确实显示了添加内容,所以我怀疑(道歉) )这只是代码中的一个错误。
答案 1 :(得分:0)
在弹出窗口中执行的脚本具有不同的上下文,因此如果您在弹出窗口中尝试此操作:
Array === window.top.Array // false