В чем разница между open() и window.open() в Firefox?

В ответе мой вопрос Pumbaa80 нашел разницу между вызовами open() и window.open(), попробуйте следующие примеры в Firefox (проверено на 11.0):

  • http://jsfiddle.net/9kqp5/ (вызовы open; открывается на новой вкладке в FF, при условии что включена опция "Открывать новые окна в новой вкладке", что по умолчанию)

  • http://jsfiddle.net/HLbLu/ (вызовы window.open; открывается в новом маленьком окне)

Но почему же существует разница? Если я попробую следующий пример:

<script>
var a = 2;
function hello() { alert(this.a); }

hello();
window.hello();
</script>

Оба варианта вызывающей функции hello работают точно так же, включая те же this!!!

Ответы

Ответ 1

Один из ваших скриптов вызывает window.open, а другой вызывает document.open, потому что цепочка областей видимости в обработчиках событий inline-атрибутов является странной. Итак, вы попадаете в http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-document-open

Тем не менее, поскольку вы передаете 3 аргумента, это должно вызывать window.open. Разница в поведении кажется ошибкой в ​​Firefox. Я зарегистрировал https://bugzilla.mozilla.org/show_bug.cgi?id=741266.

Ответ 2

Внутри обработчика событий open сам по себе решит document.open. Как отметил Борис Збарский в комментарии и в его ответе, это ожидаемое поведение, указанное HTML5. В разделе раздел о обработчиках событий, шаг 6 указывает:

6. Используя среду выполнения script, созданную выше, создайте функциональный объект (как определено в ECMAScript edition 5, раздел 13.2 Создание объектов функций), с помощью:

(...)
Лексическая область окружения

  • Пусть Scope будет результатом NewObjectEnvironment (элемент Document, глобальная среда).
  • Если элемент имеет владельца формы, пусть Scope будет результатом NewObjectEnvironment (владелец формы элемента, область действия).
  • Пусть Scope будет результатом NewObjectEnvironment (объект элемента, область действия).
    (...)

Другими словами, ссылки переменных внутри обработчика событий будут разрешены в следующем порядке:

  • локальная область
  • свойства элемента
  • свойства формы владельца (если применимо)
  • document свойства
  • глобальная область

Ответ 3

Ваши две скрипки работают одинаково для меня в Chrome.

Однако две строки кода

window.open(...);

и

open(...);

НЕ эквивалентны. Единственный раз, когда они будут эквивалентны, если ваша текущая область выполнения не предоставляет новое определение для open, заставляя интерпретатор искать в более высоких областях, пока не достигнет глобальной области, и найдет window.open.

Вы можете увидеть это в действии в этой скрипке:

var test = function () {
    var open = function () {
      alert('uh oh');  
    };

    window.open('www.google.com');
    open('www.google.com');
};

test();

Ответ 4

В браузере контекст по умолчанию - window. Поэтому вы можете вызвать open(), alert() и даже escape(), например. Вызов window.open() в точности эквивалентен open().

Как открывается новое окно вызовом функции open(), полностью зависит от вашего браузера.

Ответ 5

Это действительно очень странно. Похоже, что обработчик onclick при добавлении в качестве атрибута имеет некоторый контекст с обернутой функцией open, которая отличается от window.open:

http://jsfiddle.net/aFujb/

Это происходит в последних версиях Firefox, Safari и Chrome. Я не могу найти никакого объяснения или отчета об ошибке для любого браузера.

Я попытался выяснить, что происходит в исходном коде Firefox, но, честно говоря, это слишком много для меня. Выглядит там две разные версии window.open под названием nsGlobalWindow::Open и nsGlobalWindow::OpenJS, но я не уверен, что это имеет какое-то отношение к вопрос.

Ответ 6

На самом деле это то же самое. Попробуйте window.open === open или window["open"] === open. Если это дает вам ложь, вы должны быть в закрытии, а somecode - открытым.

И, конечно, это означает все объекты, которые являются членами глобального (окна) объекта.