Quelle est la différence entre open () et window.open () dans Firefox?

En répondant à ma question, Pumbaa80 a trouvé une différence entre l'appel open() et window.open() , essayez les exemples suivants dans Firefox (testé sur 11.0):

  1. Http://jsfiddle.net/9kqp5/ (appels open , s'ouvre dans un nouvel onglet dans FF , à condition que le paramètre "Ouvrir une nouvelle fenêtre dans un nouvel onglet à la place" soit activé, ce qui est par défaut)

  2. window.open (appels window.open ; ouvre dans une nouvelle petite fenêtre )

Mais pourquoi est-ce qu'il y a une différence? Si j'essaie l' exemple suivant :

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

Les deux variantes de la fonction d'appel hello fonctionnent exactement les mêmes, y compris en ayant la même this !!!

L'un de vos window.open appelle window.open tandis que l'autre appelle document.open , car la chaîne de portée dans les gestionnaires d'événements d'attribut en ligne est bizarre. Donc, vous vous retrouvez à http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-document-open

Cela dit, puisque vous passez 3 arguments, cela devrait invoquer window.open . La différence de comportement semble être un bug dans Firefox. J'ai déposé https://bugzilla.mozilla.org/show_bug.cgi?id=741266 à ce sujet.

À l'intérieur du gestionnaire d'événements, open lui-même se résoudra à document.open . Comme Boris Zbarsky l'a mentionné dans un commentaire et dans sa réponse , c'est un comportement attendu, spécifié par HTML5. Dans la section sur les gestionnaires d'événements , l'étape 6 spécifie:

6. À l'aide de l'environnement d'exécution du script créé ci-dessus, créez un objet fonction (tel que défini dans ECMAScript édition 5 section 13.2 Création d'objets fonctionnels), avec:

(…)
Portée environnementale Lexique

  1. Laissez le champ d'application être le résultat de NewObjectEnvironment (le document de l'élément, l'environnement global).
  2. Si l'élément possède un propriétaire de formulaire, laisser Scope être le résultat de NewObjectEnvironment (le propriétaire du formulaire de l'élément, Scope).
  3. Laissez Scope être le résultat de NewObjectEnvironment (l'objet de l'élément, Scope).
    (…)

En d'autres termes, les références variables dans le gestionnaire d'événements seront résolues dans l'ordre:

  1. Portée locale
  2. Propriétés de l'élément
  3. Propriétés du formulaire de propriétaire (le cas échéant)
  4. Propriétés du document
  5. Portée mondiale

Vos deux violons fonctionnent le même pour moi sur Chrome.

Cependant, les deux lignes de code

window.open(...);

et

open(...);

NE SONT PAS équivalents. La seule fois où ils seront équivalents, c'est si votre champ d'exécution actuel ne fournit pas une nouvelle définition pour open , ce qui amène l'interprète à regarder dans les étendues supérieures jusqu'à ce qu'il atteigne la portée globale et trouve window.open .

Vous pouvez le voir en action dans cette violon :

 var test = function () { var open = function () { alert('uh oh'); }; window.open('www.google.com'); open('www.google.com'); }; test(); 

Dans un navigateur, le contexte par défaut est une window . C'est pourquoi vous pouvez appeler open() , alert() et even escape() par exemple. Appeler window.open() équivaut exactement à open() .

La façon dont une nouvelle fenêtre s'ouvre par l'appel de fonction open() dépend entièrement de votre navigateur.

C'est vraiment très étrange. Il semble que The onclick handler soit ajouté en tant qu'attribut a un contexte avec une fonction open enveloppée qui diffère de window.open :

http://jsfiddle.net/aFujb/

Cela se produit dans les derniers Firefox, Safari et Chrome. Je ne peux pas trouver d'explication ou de rapport d'erreur pour l'un ou l'autre navigateur.

J'ai essayé de découvrir ce qui se passe dans le code source de Firefox, mais honnêtement, c'est trop pour moi atm. On dirait qu'il existe deux implémentations de window.open différentes appelées nsGlobalWindow::Open et nsGlobalWindow::OpenJS , mais je ne sais pas si cela a quelque chose à voir avec la question.

Ce sont en fait les mêmes. Essayez window.open === open ou window["open"] === open . Si cela vous rend faux alors vous devez être dans une fermeture et somecode a défini ouvert.

Et bien sûr, cela représente tous les objets qui appartiennent à l'objet global (fenêtre).