JS-BOM核心window对象

52 阅读3分钟

前言

在浏览器环境中,window 对象扮演着双重角色:它既是 JavaScript 访问浏览器窗口的接口,又是 ECMAScript 规定的 Global 对象。理解 window 的属性与方法,是掌握浏览器环境开发的第一步。

一、 Window 对象的双重身份

  1. 浏览器窗口接口:控制窗口大小、位置、导航等。
  2. 全局作用域:通过 var 声明的变量、函数都会变成 window 的属性(注意:letconst 不会)。

二、 窗口层级:Top 与 Parent 的奥秘

在处理 <iframe> 嵌套或多窗口场景时,精确定位窗口层级至关重要。

  • window.top:始终指向最外层的浏览器窗口(即最顶层的框架)。
  • window.parent:指向当前窗口的直接上层窗口。如果当前窗口本身就是顶层,则 parent 等于 self
  • window.self:指向当前窗口,与 window 等价。

同源限制:只有在同源(协议、域名、端口一致)的情况下,才能通过这些属性访问父窗口的 DOM 或变量。


三、 窗口尺寸:Inner vs Outer

很多开发者分不清这两组属性的区别,看图最直观:

属性包含内容备注
innerWidth / innerHeight仅页面视图区域(Viewport)不含工具栏、边框,包含滚动条
outerWidth / outerHeight整个浏览器窗口包含地址栏、标签栏、侧边栏、窗口边框

提示:由于不同浏览器的 UI 组件(如侧边栏、收藏夹)占用空间不同,outer 系列的值在各平台差异较大。


四、 窗口导航与弹窗控制:window.open

window.open(url, name, features, replace) 是控制页面跳转的利器。

1. 参数细节

  • name:这是一个隐藏的“黑科技”。若已存在同名窗口,浏览器会在该窗口加载 URL,而不是新建标签页。这常用于单页面应用中的跨窗口通信。
  • features:字符串格式,如 "width=400,height=300,top=100,left=100"
  • replace:布尔值。如果为 true,新页面将替换当前页在历史记录(History)中的位置,用户点击“后退”无法回到原页面。

2. 安全性与拦截处理

由于广告弹窗滥用,现代浏览器对 window.open 有严格限制:只有由用户操作(如点击事件)触发的弹窗才会被允许。

最佳实践检测代码:

// 尝试打开新窗口
let popup = window.open('https://juejin.cn', '_blank');

// 检测是否被拦截(某些插件会导致 popup 为 null,某些浏览器会抛出异常)
try {
  if (popup == null || popup.closed || typeof popup.closed === 'undefined') {
    console.warn('弹窗被浏览器拦截,请引导用户手动开启权限!');
  }
} catch (e) {
  console.error('弹窗被拦截或发生跨域错误');
}

六、 面试模拟题

Q1:window.onloadDOMContentLoaded 有什么区别?

参考回答:

  • DOMContentLoaded:当 HTML 文档被完全加载和解析完成时触发,不需要等待样式表、图像和子框架的完成加载。
  • window.onload:等整个页面所有资源(包括图片、Flash、CSS等)全部加载完成后才触发。
  • 性能建议:通常建议将脚本逻辑放在 DOMContentLoaded 中以提升响应速度。

Q2:如何通过 JS 判断当前页面是否在 iframe 中运行?

参考回答:

可以通过比较 window.self 和 window.top:

if (window.self !== window.top) {
  console.log('当前页面运行在 iframe 中');
}

Q3:为什么不建议在全局作用域中使用变量名 name

参考回答:

因为 window.name 是一个内置的特殊属性。它有一个特性:即使页面刷新或跳转到另一个域名,window.name 的值也会持久存在(直到窗口关闭)。如果你在全局定义了 var name = 'test',实际上是在修改这个内置属性,可能会引发意外的行为。