Firefox中的open()和window.open()有什么区别?

时间:2012-04-01 16:43:06

标签: javascript firefox window

在回答my question Pumbaa80 found调用open()window.open()之间的区别时,请尝试以下示例 (在11.0上测试):

  1. http://jsfiddle.net/9kqp5/(调用open; 在FF 的新标签页中打开,前提是“在新标签页中打开新窗口”设置已启用,默认情况下)

  2. http://jsfiddle.net/HLbLu/(调用window.open; 在新的小窗口中打开

  3. 但为什么地球上有区别呢?如果我尝试following example

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

    调用函数hello的两个变体完全相同,包括具有相同的this !!!

6 个答案:

答案 0 :(得分:8)

其中一个小提琴正在调用window.open而另一个正在调用document.open,因为内联属性事件处理程序中的作用域链很奇怪。所以你最终到了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

答案 1 :(得分:6)

在事件处理程序中,open本身将解析为document.open。正如Boris Zbarsky在评论和his answer中提到的,这是HTML5指定的预期行为。在the section on event handlers中,第6步指定:

  

6。使用上面创建的脚本执行环境,创建一个   功能对象(在ECMAScript第5版第13.2节中定义   创建函数对象),包括:

     

(...)
  词汇环境范围

     
      
  1. 让Scope成为NewObjectEnvironment(元素的Document,全局环境)的结果。
  2.   
  3. 如果元素具有表单所有者,则让Scope为NewObjectEnvironment(元素的表单所有者,Scope)的结果。
  4.   
  5. 让Scope成为NewObjectEnvironment(元素的对象,Scope)的结果   (...)
  6.   

换句话说,事件处理程序中的变量引用将按以下顺序解析:

  1. 本地范围
  2. 元素属性
  3. 所有者表单属性(如果适用)
  4. document属性
  5. 全球范围

答案 2 :(得分:4)

你的两个小提琴在Chrome上对我有同样的作用。

然而,两行代码

window.open(...);

open(...);

不等同。它们唯一相同的时间是当前执行范围没有为open提供新定义,导致解释器查看更高的范围,直到它到达全局范围并找到window.open。 / p>

您可以在this fiddle中看到这一点:

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

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

test();

答案 3 :(得分:1)

在浏览器中,默认上下文为window。这就是为什么你可以拨打open()alert()甚至escape()的原因。致电window.open()完全等同于open()

open()函数调用打开新窗口的方式完全取决于您的浏览器。

答案 4 :(得分:1)

这确实很奇怪。看起来onclick处理程序作为属性添加时具有一些带有open函数的上下文,该函数与window.open不同:

http://jsfiddle.net/aFujb/

这种情况发生在最新的Firefox,Safari和Chrome中。我无法找到任何浏览器的任何解释或错误报告。

我试图找出Firefox源代码中发生了什么,但老实说,这对我来说太过分了。看起来two different window.open implementations名为nsGlobalWindow::OpennsGlobalWindow::OpenJS,但我不确定这是否与此问题有关。

答案 5 :(得分:0)

事实上是一样的。试试window.open === openwindow["open"] === open。 如果这对你产生错误,那么你必须在一个闭包中,而某些代码已定义为open。

当然,这代表了作为全局(窗口)对象成员的所有对象。