window.location和document.location有什么区别?

319

window.location和document.location有什么区别?它们是否都应该引用相同的对象?


4
要展示它们之间差异的用例,请参见https://dev59.com/yXE95IYBdhLWcg3wKqok#12098898。 - Pacerier
这里也可以找到一篇好的阅读材料:https://html.spec.whatwg.org/multipage/nav-history-apis.html#the-location-interface。特别是所提供的警告(“Location异类对象是通过IDL的混合,创建后调用JavaScript内部方法以及重写JavaScript内部方法来定义的。再加上其可怕的安全策略,请在实现此物体时格外小心。”)值得注意。 - Elmar Zander
18个回答

289

14
被踩了。回答有矛盾之处。它大胆地说它们是相同的,然后用较浅的文字描述它们的区别。它们显然不是同一个东西。 - danorton
55
来吧,容易激动的点踩者们,放轻松一点。就大部分而言,根据 rahul 指定的限制条件,它们的行为相似。我们不应该在语义上纠缠不清。绅士们,请保持一点费城精神。就我个人而言,我觉得他的答案完全令人满意。+1(Christoph 的答案应该被采纳,但是 rahul 的答案也可以接受——至少不值得被踩。) - cssyphus
11
在未提供任何理由的情况下建议使用“window.location”作为最佳实践被评为-1分。如果您不提供理由,为什么有人应该采纳您的建议?在这方面,Christoph的回答要更有用。 - Mark Amery
+1 但是请注意下面Phil Hamer和Christoph的回答,它们提供了必要的背景信息和注意事项,以便完全理解这个问题。 - Jon z

240

获取当前位置对象的规范方法是 window.location(参见1996年的此MSDN页面和2006年的W3C草案)。

相较于最初仅返回当前URL字符串的 document.location(请参见这个MSDN页面),很可能为了避免混淆,document.location被替换成了 document.URL(请参见此MSDN页面),它也是DOM Level 1的一部分。

据我所知,所有现代浏览器将 document.location 映射到 window.location,但我仍然更喜欢使用 window.location,因为这是我从编写我的第一个 DHTML 开始就一直在使用的。


2
如果你使用 window.location,那么仅使用 location 是否同样有效呢? - commonpike
10
在HTML文档中的脚本上下文中,全局对象是指定义的所有变量都成为其属性的对象,即window对象。因此,在脚本的顶层定义的任何变量或函数都是window对象的属性,而window对象恰好是全局对象。如果省略全局对象,它将被隐含地认为是window.,所以location被解释为window.location。需要注意的是,例如if(an_undefined_variable)会在变量未定义时抛出错误,但是if(window.an_undefined_variable)不会。 - Armen Michaeli
@commonpike,是的,只要您在符合标准的浏览器环境中,并且本地作用域中没有不同的变量“location”。 - Paul Draper

96

window.location在所有兼容的浏览器中都是可读写的。

document.location在Internet Explorer (至少)中只能读取,但在基于Gecko的浏览器 (Firefox, SeaMonkey) 中是可读写的。


13
我无法复现“document.location在IE中是只读的”这一说法。我可以在IE 10、9、8和6中成功地对其进行赋值(使用来自http://modern.ie的虚拟机)。 - Mark Amery

49

40

有趣的是,如果你有一个名为 'location' 的frame、image或form,那么'document.location'会分别提供对应的frame窗口、image或form的引用,而不是Location对象。显然,这是因为document.forms、document.images和window.frames集合名称查找优先于映射到window.location。

<img name='location' src='location.png'>

if (document.location.tagName == 'IMG') alert('Hello!')

2
没有优先级,它只是被覆盖 - Pacerier
10
不,它没有被覆盖。它被隐藏了,所以Phil关于元素在属性解析期间优先级更高是正确的。 - kangax
@kangax,似乎你是正确的:http://jsfiddle.net/uL4ysszr/。但这种行为有多可靠?它是否足够跨浏览器? - Pacerier
我认为它在各种浏览器上都能很好地运行,不幸的是,我没有时间去检查,但如果我没记错的话,你应该能够在HTML5规范中找到这种行为。 - kangax
1
刚刚测试了一下(2016年10月)。似乎在Chrome或Firefox中无法遮蔽window.locationdocument.location - Mr. Llama
1
@Mr.Llama 您是正确的。所有现代浏览器似乎不再像我上面描述的那样行为了。这似乎是由于给document.location赋予了“Unforgeable”属性所致。 相关的Chromium更改:https://src.chromium.org/viewvc/blink?view=revision&revision=189862 以及Firefox错误:https://bugzilla.mozilla.org/show_bug.cgi?id=1133760 - Phil Hamer

29
据我所知,两者是相同的。为了跨浏览器安全,您可以使用 window.location 而不是 document.location
所有现代浏览器将 document.location 映射到 window.location,但我仍然更喜欢使用 window.location,因为这是我编写第一个网页时就使用的方式,它更加一致。
您还可以看到 document.location === window.location 返回 true,这澄清了两者是相同的。

16

document.location === window.location 返回 true

另外

document.location.constructor === window.location.constructor 也是 true

注意:这是在测试了 Chrome、Firefox 3.6、Opera 10 和 IE6 后得出的结论。


1
@Pacerier 为什么?对于对象来说,===== 是等价的。 - Mark Amery
6
@MarkAmery,这是错误的,可以很容易地证明:"abc" == new String("abc") 返回 true,而 "abc" === new String("abc") 返回 false - Pacerier
9
好的,让我稍微更加严谨并且更不含糊地陈述:当比较两个对象时(而不只是将一个对象与任何东西进行比较),=====是等价的。参见规范的11.9.3和11.9.6章节。对于非null、非undefined、非数字、非布尔、非字符串类型的值,它们具有相同的类型,==的行为受11.9.3部分1f的约束,而===的行为则受11.9.6部分7的约束,这两部分都是完全相同的:如果x和y引用了同一个对象,则返回true。否则,返回false。 - Mark Amery
16
@MarkAmery,不能保证document.locationwindow.location都指向对象。你错过了全等符号的整个意义;使用两个等于号不能证明它们是同一个对象我们应该使用三个等号而不是两个等号,因为两个等号会给我们一个错误的结果。在一个浏览器中,其中document.location是一个与window.location.toString()相等的URL字符串时,document.location==window.location将返回true,而document.location===window.location将返回false。 - Pacerier
1
@Pacerier 哦,我终于明白了。你说得很对,至少在 document.location === window.location 比较方面是这样的。.constructor 比较也被加入其中,我认为这个答案仍然是正确的,但使用 === 会简化推理过程。 - Mark Amery
显示剩余2条评论

12

是的,它们是相同的。这是浏览器JS API中许多历史怪癖之一。尝试执行:

window.location === document.location

9

window.location是两者中更加可靠且一致的,特别是对于旧浏览器而言。


4

如今很少见到这种区别,因为HTML 5不再支持框架集。但是在过去,当我们还有框架集时,document.location只会重定向执行代码的框架,而window.location则会重定向整个页面。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接