【JavaScript】二十四、JS的执行机制事件循环 + location + navigator + history
文章目录
- 1、JS执行机制(事件循环eventloop)
- 2、BOM的window
- 3、location对象
- 3.1 href属性
- 3.2 search属性
- 3.3 hash属性
- 3.4 reload方法
- 4、navigator对象
- 5、history对象
1、JS执行机制(事件循环eventloop)
以下,两段代码输出结果一样,都会 1111 -> 3333 -> 2222
JS语言本身是单线程的,同一个时间只能做一件事,因为其使命是操作DOM,从上而下很合理,但如果有部分JS代码执行很慢,就会造成页面渲染不连贯,因此,HTML5提出标准,允许JavaScript脚本创建多个线程,由此,再JS中也有了同步和异步:
- 同步:串行,一个个的执行,比如:烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜
- 异步:做一个事的时候,可以同时去做另外的事,比如:在烧水的同时,利用这10分钟,去切菜,炒菜
以上面console.log打印顺序的问题为例,分析JS代码的执行机制:
-
同步任务都在主线程上执行,形成一个执行栈
-
JS 的异步是通过回调函数实现的,异步任务相关的则添加到任务队列中去,异步任务主要包括:
-
普通事件,如 click、resize 等(事件什么时候会被用户触发,是不确定的)
-
资源加载,如 load、error 等
-
定时器,包括 setInterval、setTimeout 等
如上,代码执行的时候,先执行 JS执行栈中的同步任务,一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务(异步任务完毕了,会被推到任务队列中,哪个时间先到了,哪个就被先推到任务队列,也就先被JS主线程执行),这也就是为什么开篇setTimeout等待时间即使是0,也是最后才被执行到原因
如上,JS的主线程在不断的重复🔁获得任务、执行任务、再获取任务、再执行,因此,JS的执行机制,被称为事件循环eventloop
上面这段代码,结果可能是1、2、3、4也可能是1、2、4、3,这取决于定时任务和点击事件哪个先到时间,被推到了任务队列
2、BOM的window
BOM,Browser Object Model,浏览器对象模型,BOM下有一个window对象,是一个全局对象,它是JS中的顶级对象,而之前DOM中常用的document,只不过是window的一个属性,因此,也可以看出BOM > DOM,DOM是BOM的一个子集。关于window:
- 像document、alert()、console.log()这些都是window的属性
// true
document === window.document
- 所有通过var定义在全局作用域中的变量、函数都会变成window对象的属性和方法,而window对象下的属性和方法调用的时候又都可以省略window
function fn() {console.log(1)
}// 可以省略为fn()
window.fn()
var num = 10
// 10
console.log(window.num)
// 注意const定义的不是
const num = 10
// undefined
console.log(window.num)
3、location对象
location,数据类型obj,它里面保存了URL地址的各个部分,常用属性和方法有:
- href
- search
- hash
- reload
3.1 href属性
href 属性获取完整的 URL 地址,对其赋值可以实现跳转到赋值的地址
// true
console.log(location === window.location)
// 可以得到当前文件的URL地址
console.log(location.href)
// 除了a标签点击跳转,也可用JS的方式去实现跳转
location.href = 'http://www.baidu.com'
案例:5秒钟之后跳转的页面
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>span {color: red;}</style>
</head><body><!-- 点击跳转是a标签 --><a href="http://www.baidu.com">支付成功, <span>5</span>秒后自动跳转, 点击立即跳转</a><script>let second = 5const a = document.querySelector('a')// 自动跳转并更新剩余时间let timerId = setInterval(function () {second--a.innerHTML = `支付成功, <span>${second}</span>秒后自动跳转, 点击立即跳转`if (second === 0) {clearInterval(timerId)location.href = 'http://www.baidu.com'}}, 1000)</script>
</body></html>
3.2 search属性
search属性可以获取地址中携带的参数,即符号?后面的部分
<body><form action=""><input type="text" name="username"><input type="password" name="pwd"><button>提交</button></form>
</body>
输入用户名密码后点击提交:
3.3 hash属性
hash属性用于获取地址中的哈希值,即符号#后面的部分
可以看到,点击网易云上面每一个选项,URL中的#后面的路径在变(另外的,页面并没有跳转,而是部分改变 ⇒ spa,single page web application)
<body><a href="#/my">我的</a><a href="#/download">下载</a><a href="#/friend">朋友</a>
</body>
3.4 reload方法
用于刷新当前页面,传入参数true时,表示强制刷新,类似Ctrl + F5,不传,就是普通刷新
<body><button>点我强刷</button>
</body>
<script>const btn = document.querySelector('button')btn.addEventListener('click', function () {location.reload(true)})
</script>
4、navigator对象
navigator,导航器,obj类型,该对象下记录了浏览器自身的相关信息,如通过userAgent属性检测浏览器的版本和平台
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script>// 立即执行函数// 检测 userAgent(浏览器信息) !(function () {const userAgent = navigator.userAgent// 验证是否为Android或iPhoneconst android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/)const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/)// 如果是Android或iPhone,则跳转至移动站点 if (android || iphone) {location.href = 'http://www.baidu.com'}})()</script>
</head><body>这是PC端页面
</body></html>
打开页面:
F12切换下工具,再刷新,成功跳转到百度:
5、history对象
history,obj类型,管理历史记录,该对象与浏览器地址栏的前进、后退、历史记录操作相对应,常用方法:
<body><button>前进</button><button>后退</button><script>const back = document.querySelector('button:first-child')const forward = back.nextElementSiblingback.addEventListener('click', function () {//history.go(-1)history.back()})forward.addEventListener('click', function () {//history.go(1)history.forward()})</script>
</body>