Нет, это не ошибка (по крайней мере, не в браузере), и это не просто IE.
Каждый документ, который показывает браузер, имеет собственную глобальную среду, включая прототипы для основных объектов. Они все с чистого листа. Конструктор Array
в одном документе отличается от конструктора Array
в другом документе, и эти конструкторы не имеют общего свойства prototype
; среды отключены. Вот почему instanceof
плохо работает в многодокументных веб-приложениях.
Рассмотрим этот пример ( живая копия ):
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
, отличного от объекта в нашем окне, и поэтому не содержит добавлений, которые мы сделали к нашему Array.prototype
. Затем он создает экземпляр массива, который имеет , имеет эти дополнения и передает его во всплывающее окно, которое правильно видит дополнения (поскольку объект продолжает ссылаться на свой первоначальный прототип):
Вывод в главное окно:
Добавление свойства к Array.prototype
Локальное тестирование недвижимости, [].__foo = bar
Открытие всплывающего окна
Ожидание загрузки окна ...
Окно загружено, получая массив из него
a
содержание: 1, 2, 3
a.__foo = undefined
a instanceof Array
? ложный
wnd.Array === Array
? ложный
Создание b
b.__foo = bar
Передав b
всплывающему окну, посмотрите на результат.
... и во всплывающем окне:
Я всплывающее окно.
Получено x
: 3,4,5
x.__foo = bar
Вы увидите этот вывод как в IE (я специально тестировал IE9, но он работает и в IE7, и, я уверен, в других), так и в других браузерах.
Окружения в двух разных окнах могут общаться друг с другом, но у них нет общих глобалов; Array.prototype
в родительском окне никак не наследуется дочерним окном.
В комментариях вы сказали, что при передаче массива из главного окна в дочернее окно добавления «исчезают». (В вашем коде ничего не показано, что вы делаете это.) Из вышесказанного видно, что на самом деле объект поддерживает свои отношения с его прототипом правильно и действительно показывает дополнения, поэтому я подозреваю (с извинениями) это просто ошибка в вашем коде.