开始阅读JavaScript高级程序设计(第5版)学习JS,总共有1000+页,非常全面,短期看完不太现实,找到了一篇博客,花些时间跟着这篇博客过一下红宝书。
红宝书《JavaScript高级程序设计(第5版)》学习大纲 - 大前端全栈开发 - SegmentFault 思否
全文概览:
| 重要度 | 知识点 | 理由 |
|---|---|---|
| ⭐⭐⭐ | location 既是 window 也是 document 的属性(window.location === document.location) | 基础概念,面试可能追问”两个location有什么区别” |
| ⭐⭐⭐ | location URL 解析属性(hash/search/hostname/pathname/port/href 等) | 开发高频使用,解析/拼接 URL 必备,面试可能问”如何获取 URL 参数” |
| ⭐⭐⭐ | location.assign() vs location.replace()(是否增加历史记录) | 路由跳转核心区别,面试常问”assign和replace区别” |
| ⭐⭐⭐ | location.hash 修改不重载页面,其他属性修改会重载 | SPA 路由基础,面试可能问”改变hash会刷新页面吗” |
| ⭐⭐⭐ | history.pushState() / replaceState() / popstate 事件 | SPA 路由核心原理,Vue Router / React Router 底层依赖,面试必问 |
| ⭐⭐⭐ | pushState() 假 URL 需真实后端对应(否则刷新 404) | SPA 部署经典坑,面试可能问”history模式刷新404怎么解决” |
| ⭐⭐⭐ | location.reload() vs location.reload(true)(缓存 vs 强制服务器) | 实际开发常用,面试可能问”如何强制刷新页面” |
| ⭐⭐ | location.href = url 等价 assign(),是最常见的跳转写法 | 开发中最常用的导航方式,知道三种写法等价即可 |
| ⭐⭐ | history.go() / back() / forward() / length | 基础导航 API,知道有这些方法即可 |
| ⭐⭐ | location.search 与 URLSearchParams API 配合使用 | 实际开发中解析查询参数常用,面试可能追问 URLSearchParams |
| ⭐⭐ | history.state 读取当前状态 | 配合 pushState/replaceState 使用,知道可以读取即可 |
| ⭐⭐ | navigator.userAgent 浏览器检测 | 实际开发中偶尔用于兼容性判断,但现代推荐特性检测而非 UA 检测 |
| ⭐⭐ | navigator.registerProtocolHandler() | 知道有这个 API 即可,PWA 相关,低频但面试可能作为扩展知识问 |
| ⭐ | location 完整 URL 结构(含 userinfo 如 foouser:barpassword@) | 了解即可,实际开发中几乎遇不到带凭据的 URL |
| ⭐ | screen 对象(客户端显示器信息) | 实际开发几乎不用,知道有这么个对象即可 |
| ⭐ | screen.width / screen.height / screen.availWidth 等 | 极少使用,响应式开发用 window.innerWidth 而非 screen |
| ⭐ | navigator 其他属性(language/cookieEnabled/onLine 等) | 个别属性偶尔用到(如 onLine 检测网络),但整体不考 |
| ⭐ | history.go() 传入字符串导航 | 旧特性,现代浏览器不支持,不考 |
| ⭐ | pushState() state 对象大小限制(500KB~1MB) | 了解即可,实际不会存这么大的状态 |
| ⭐ | pushState() 第二个参数(标题)未被实现 | 知识细节,不影响开发 |
location对象:
location是最有用的BOM对象之一,提供了当前窗口中加载的文档的信息,以及通常的导航功能。
这个对象独特的地方在于,它既是window的属性,也是document的属性。也就是说,window.location和document.location指向同一个对象。
location对象不仅保存着当前加载文档的信息,也保存着把URL解析为离散片段后能够通过属性访问的信息。这些解析后的属性在下表中有详细说明(location前缀是必需的)。
假设浏览器当前加载的URL是http://foouser:barpassword@www.wiley.com:80/WileyCDA/?q=javascript#contents,location对象的内容如下表所示。
在处理location对象时,URL API和URLSearchParams API非常有用。详情请参阅第18章。
location操作地址:
导航到新 URL:
window.open也可以实现类似功能,但window.open可以打开新窗口,也可以不打开,而assign()无法打开新窗口。当window.open的第二个参数target为_self时就等同于location.assign()。它们是同一件事的不同入口。
window.open()更通用,既能新开也能当前窗口跳转;location.assign()只做当前窗口跳转,但语义更明确。
最常见的是 assign() 方法:
1
location.assign("http://www.wiley.com");
这会立即导航到新 URL,并在浏览器历史记录中增加一条记录。以下两种写法效果和 assign() 完全相同:
1
2
window.location = "http://www.wiley.com";
location.href = "http://www.wiley.com";
三种方式中,设置 location.href 是最常见的。
修改 URL 的各个部分:
修改 location 对象的属性也会修改当前 URL 并触发页面重新加载:
1
2
3
4
5
6
7
// 假设当前 URL 为 http://www.wiley.com/WileyCDA/
location.hash = "#section1"; // → …/WileyCDA/#section1
location.search = "?q=javascript"; // → …/WileyCDA/?q=javascript
location.hostname = "www.example.com"; // → http://www.example.com/WileyCDA/
location.pathname = "mydir"; // → …/mydir/
location.port = 8080; // → …:8080/WileyCDA/
关键区别:
hash:修改后不会重新加载页面,但会在浏览器历史中增加一条记录- 其他属性:修改后都会重新加载页面
所有这些修改都会在历史记录中增加一条记录,用户可以点”后退”回到前一页。
replace() :不留历史记录的跳转
如果不希望增加历史记录(用户无法后退),使用 replace():
1
2
3
4
5
location.replace("http://www.wiley.com/");
// 和assign的对比
location.assign("http://...") // 新增记录 → 能后退
location.replace("http://...") // 替换当前记录 → 不能后退
调用后用户不能通过”后退”按钮返回前一页,除非手动输入完整 URL。
reload() :重新加载当前页面
1
2
location.reload(); // 可能从缓存加载
location.reload(true); // 强制从服务器加载
- 不传参数:以最有效的方式重新加载,如果页面未修改过,可能从缓存加载
- 传
true:强制从服务器重新加载
reload()之后的代码可能执行也可能不执行,取决于网络延迟和系统资源。最好把reload()作为最后一行代码。
地址操作方法对比:
| 方法/属性 | 是否加载新页面 | 是否增加历史记录 |
|---|---|---|
assign(url) | ✅ | ✅ |
location.href = url | ✅ | ✅ |
location.hash = val | ❌ | ✅ |
| 其他属性(search/port 等) | ✅ | ✅ |
replace(url) | ✅ | ❌ |
reload() | ✅ | — |
navigator对象:
navigator是由Netscape Navigator 2最早引入浏览器的,现在已经成为客户端标识浏览器的标准。只要浏览器启用JavaScript,navigator对象就一定存在。但是与其他BOM对象一样,每个浏览器都支持自己的一组属性。
navigator对象的属性通常用于确定浏览器的类型。
注册处理程序:
navigator上的registerProtocolHandler()方法可以把一个网站注册为处理某种特定类型信息。在线RSS阅读器和电子邮件客户端可以借助这个方法将Web应用程序注册为像桌面软件一样的默认应用程序。 要使用registerProtocolHandler()方法,必须传入3个参数:要处理的协议(如”mailto” 或 “ftp”)、处理该协议的URL,以及应用名称。比如,要把一个Web应用程序注册为默认邮件客户端,可以这样做:
1
2
3
navigator.registerProtocolHandler("mailto",
"http://www.example.com?cmd=%s",
"Some Mail Client");
这个例子为 “mailto” 协议注册了一个处理程序,这样邮件地址就可以通过指定的Web应用程序打开。注意,第二个参数是负责处理请求的URL,%s表示原始的请求。
screen对象:
window的另一个属性screen对象是为数不多的几个在编程中很少用到的JavaScript对象之一。这个对象中保存的纯粹是客户端能力信息,也就是浏览器窗口外面的客户端显示器的信息,比如像素宽度和像素高度。每个浏览器都会在screen对象上暴露不同的属性。下表总结了这些属性。
history对象:
history对象表示自当前窗口首次使用以来用户的导航历史记录。因为history是window的属性,所以每个window都有自己的history对象。
出于安全考虑,这个对象不会暴露用户访问过的URL,但可以通过它在不知道实际URL的情况下前进和后退。
导航:
go() 任意方向导航:
接收一个整数参数,表示前进或后退多少步:
1
2
3
history.go(-1); // 后退一页(等同点击"后退"按钮)
history.go(1); // 前进一页(等同点击"前进"按钮)
history.go(2); // 前进两页
旧版浏览器中参数也可以是字符串,浏览器会导航到历史记录中包含该字符串的最近位置(可能前进也可能后退),没有匹配则什么也不做:
1
history.go("wiley.com"); // 导航到最近的 wiley.com 页面
简写方法:
1
2
history.back(); // 后退一页,等同 go(-1)
history.forward(); // 前进一页,等同 go(1)
length 属性:
history.length 表示历史记录中的条目数量(包括可以前进和后退的页面)。对于标签页中加载的第一个页面,history.length === 1:
1
2
3
if (history.length == 1) {
// 这是用户窗口中的第一个页面
}
hash 与历史记录:
页面 URL 变化(包括 location.hash 的改变)会在历史记录中生成新条目。这个行为常被单页应用程序(SPA)框架用来模拟前进和后退,修改 hash 不会触发页面刷新,但能产生历史记录,从而让浏览器的前进/后退按钮正常工作。
历史状态管理:
现代 Web 应用中,“后退”/“前进”按钮对用户来说意味着”切换状态”,而不是刷新页面。HTML5 为 history 对象增加了状态管理 API,可以让开发者改变浏览器 URL 而不加载新页面。
pushState() 推入历史记录:
接收 3 个参数:state 对象、新状态标题、(可选的)相对 URL。
1
2
let stateObject = { foo: "bar" };
history.pushState(stateObject, "My title", "baz.html");
执行后:
- 状态信息被推入历史记录
- 浏览器地址栏变为新 URL
- 浏览器不会向服务器发送请求(即使
location.href返回新地址)
参数注意:
- 第一个参数应包含正确初始化页面状态所需的信息,大小限制通常 500KB~1MB
- 第二个参数当前未被实现,传空字符串或短标题即可
- state 对象只应包含可序列化的信息,DOM 元素等不适合放入
popstate 事件:后退/前进时触发
pushState() 创建了新的历史记录,用户点击”后退”按钮时会触发 window 上的 popstate 事件。事件对象的 state 属性包含通过 pushState() 传入的 state 对象:
1
2
3
4
5
6
7
window.addEventListener("popstate", (event) => {
let state = event.state;
if (state) {
processState(state); // 根据状态重置页面
}
// 页面初次加载时 state 为 null
});
浏览器不会自动帮你恢复页面状态,需要根据 state 对象手动重置。页面初次加载时
event.state为null。
replaceState():替换当前状态
与 pushState() 参数相同,但不会创建新历史记录,只覆盖当前状态:
1
history.replaceState({ newFoo: "newBar" }, "New title");
读取当前状态:
1
history.state; // 获取当前状态对象
注意:假 URL 需要真实后端
通过 pushState() 创建的每个”假”URL 背后都应对应服务器上一个真实的物理 URL,否则用户点击刷新会导致 404。所有单页应用(SPA)框架都必须通过服务器或客户端配置解决这个问题。
方法总结:
| 方法 | 历史记录 | 用途 |
|---|---|---|
pushState(state, title, url) | 新增一条 | 导航到新状态 |
replaceState(state, title) | 不增加 | 更新当前状态 |
popstate 事件 | — | 后退/前进时恢复页面 |


