6

In answering my question Pumbaa80 found a difference between calling open() and window.open(), try the following examples in Firefox (tested on 11.0):

  1. http://jsfiddle.net/9kqp5/ (calls open; opens in new tab in FF, provided that the "Open new windows in new tab instead" setting is on, which it is by default)

  2. http://jsfiddle.net/HLbLu/ (calls window.open; opens in new small window)

But why on earth there is a difference? If I try the following example:

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

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

Both variants of calling function hello work exactly the same, including having the same this!!!

Community
  • 1
  • 1
Tomas
  • 57,621
  • 49
  • 238
  • 373
  • 1
    works same for me, all you sample open the same thing. And indeed they are same thing, unless you define another fucntion call open – Eric Yin Apr 01 '12 at 16:45
  • Both of the JS Fiddles exhibit the same behaviour (opening a new window) for me, too. – David Thomas Apr 01 '12 at 16:47
  • Same here, tried Opera and Firefox. – Imp Apr 01 '12 at 16:50
  • My Firefox (3.6.21) behaves as expected (`window.open` is the same as `open`) and both those Fiddles open a new window. However, I suppose it's possible that later versions have subtly changed the definition in order to cater for tabs. – Andrew Leach Apr 01 '12 at 16:52
  • Sorry to all! I wanted to mention there is a difference in Firefox, but accidentally deleted it, it is only in the keywords. Added it again! The difference in firefox is more described in the [linked question](http://stackoverflow.com/a/9962756/684229). – Tomas Apr 01 '12 at 16:54
  • Updated my question a bit. The condition is that "Open new windows in new tab instead" option is on, which it is by default. – Tomas Apr 01 '12 at 17:06

6 Answers6

7

One of your fiddles is calling window.open while the other is calling document.open, because the scope chain in inline attribute event handlers is weird. So you end up at http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#dom-document-open

That said, since you pass 3 arguments, this should be invoking window.open. The difference in behavior seems to be a bug in Firefox. I filed https://bugzilla.mozilla.org/show_bug.cgi?id=741266 on that.

Boris Zbarsky
  • 34,758
  • 5
  • 52
  • 55
  • No Boris, you shouldn't have posted that bugreport! I need this feature!!! [I need to be able to open a legend in small new windows](http://stackoverflow.com/q/9956827/684229)! – Tomas Apr 02 '12 at 08:34
  • The point of the bug report is that right now `document.open` and `window.open` have different behavior in your case: the former opens a new tab and the latter opens a small new window. They should have the same behavior, and that behavior should be to open a small new window. Which is what the patch I wrote does; you should take a look at the patch and particularly at the test in it. – Boris Zbarsky Apr 02 '12 at 13:43
  • Boris, I'm afraid the trend is to disable opening new windows.. and calling `window.open` was last chance to do it. I'm afraid they will solve the bug the other way: `window.open` will behave the same way as `document.open`, i.e. both will go to the new tab (provided you have set "Open new windows in a new tab instead" in FF properties, which is the default). – Tomas Apr 02 '12 at 13:49
  • Thre is no "they". The person solving the bug is me. The `window.open` behavior is the way it is for a reason, and the fact that `document.open` did something different was just a bug. Fixed now. – Boris Zbarsky Apr 02 '12 at 15:28
  • Aaaah, I see "Assigned To: Boris Zbarsky"! So "they" is in fact you? :-) Good! – Tomas Apr 02 '12 at 15:39
  • Accepted Boris' answer as the key one and most complete, however the first paragraph is much more clearer from the Cheran's answer. – Tomas Apr 12 '12 at 22:28
  • Per the whatwg link and noted behavior, though, it is *not* a bug... `document.open` is just a poor overload function that *requires* the first 3 parameters to act like `window.open`. (Unless I read it entirely wrong.) –  Jun 06 '12 at 00:53
  • You read it wrong. `document.open` with three arguments just tail-calls to `window.open`. – Boris Zbarsky Jun 06 '12 at 01:46
6

Inside the event handler, open by itself will resolve to document.open. As Boris Zbarsky mentioned in a comment and in his answer, this is expected behavior, specified by HTML5. In the section on event handlers, step 6 specifies:

6. Using the script execution environment created above, create a function object (as defined in ECMAScript edition 5 section 13.2 Creating Function Objects), with:

(...)
Lexical Environment Scope

  1. Let Scope be the result of NewObjectEnvironment(the element's Document, the global environment).
  2. If the element has a form owner, let Scope be the result of NewObjectEnvironment(the element's form owner, Scope).
  3. Let Scope be the result of NewObjectEnvironment(the element's object, Scope).
    (...)

In other words, variable references within the event handler will be resolved in the order:

  1. local scope
  2. element properties
  3. owner form properties (if applicable)
  4. document properties
  5. global scope
Community
  • 1
  • 1
Cheran Shunmugavel
  • 8,319
  • 1
  • 33
  • 40
  • Aha, good job! A very strange behaviour though. It's like the handler is wrapped in nested `with` blocks. I never would have expected that. – user123444555621 Apr 02 '12 at 07:10
  • @Pumbaa80 Nested with blocks is exactly what the behavior is like. Yes, it's wacky, but it's been that way forever in browsers, and tons of sites depend on it, unfortunately. – Boris Zbarsky Apr 02 '12 at 13:44
4

Your two fiddles work the same for me on Chrome.

However, the two lines of code

window.open(...);

and

open(...);

are NOT equivalent. The only time they will be equivalent is if your current executing scope does not provide a new definition for open, causing the interpreter to look in the higher scopes until it reaches the global scope and finds window.open.

You can see this in action in this fiddle:

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

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

test();
jbabey
  • 45,965
  • 12
  • 71
  • 94
  • Yes, this is obvious, but if you look at the two fiddles in my question, they both call `open` in the global context and still there is a difference! – Tomas Apr 01 '12 at 16:55
  • @Tomas I think you need to specify the version of Firefox you're using. So far no-one has reproduced the phenomenon. – Andrew Leach Apr 01 '12 at 16:59
  • @AndrewLeach, the newest one of course... (this is the default :-)). Version 11.0. – Tomas Apr 01 '12 at 17:01
1

The are in fact the same. Try window.open === open or window["open"] === open. If that yields false to you then you must be in a closure and somecode has defined open.

And of course this stands for all the objects that are member of the global (window) object.

Peter Aron Zentai
  • 11,482
  • 5
  • 41
  • 71
1

This is indeed very strange. It looks like The onclick handler when added as an attribute has some context with a wrapped open function that differs from window.open:

http://jsfiddle.net/aFujb/

This happens in latest Firefox, Safari and Chrome. I can't find any explanation or bug report for either browser.

I tried to find out what's happening in Firefox's source code, but quite honestly it's too much for me atm. Looks there's two different window.open implementations called nsGlobalWindow::Open and nsGlobalWindow::OpenJS, but I'm not sure whether this has something to do with the question.

user123444555621
  • 148,182
  • 27
  • 114
  • 126
  • Finally someone! Thanks for your investigation, Pumbaa. – Tomas Apr 01 '12 at 20:45
  • 1
    It's not a bug. In your fiddle, the bareword lookup for `open` is happening in an `onclick` _attribute_, so it's looked up on the element the attribute is on, then on the document, then on the window. And so of course it finds `document.open` before it ever gets to the window... – Boris Zbarsky Apr 02 '12 at 01:15
  • @BorisZbarsky is right; see [my answer](http://stackoverflow.com/a/9970045/249624) for an explanation of why. – Cheran Shunmugavel Apr 02 '12 at 01:53
0

In a browser, the default context is window. That's why you can call open(), alert() and even escape() for example. Calling window.open() is exactly equivalent to open().

How a new window opens by the open() function call is entirely dependent on your browser.

Eli Sand
  • 1,032
  • 7
  • 11
  • But how do you explain the difference of the two fiddles? – Tomas Apr 01 '12 at 16:58
  • There is no difference. With new windows set to open as tabs in the browser, they open as tabs. With that unset, they open as windows. You'd have to specify what browser and version you see the difference in and what your new window policies are. Make sure you don't have any special plugins running that may be affecting new windows/tabbed browsing. – Eli Sand Apr 01 '12 at 17:04
  • Pumba [observed the same difference here](http://stackoverflow.com/a/9962756/684229)... I don't have any special tabbed plugins, with just FF 11.0 with Firebug, Web developer toolbar and RealPlayer browser record Add-ons. See the note about the settings I updated in my question. – Tomas Apr 01 '12 at 17:10
  • Don't know what to tell you - everyone here has been saying the same thing; they can't reproduce what you're experiencing. Short of getting someone to look at the full output of your about:config from Firefox, I would believe it's either a plugin you're unaware of, or a lingering setting that's in your Firefox profile (did you upgrade to 11, or is this using a new profile?). – Eli Sand Apr 01 '12 at 17:17