JavaScript:从JS的执行机制到location对象
一、JS执行机制
(1)JS是单线程
JavaScript语言的一大特点就是单线程,也就是同一时间只能做一件事。因为JavaScript是为了处理页面中的用户交互,以及制作DOM二诞生的。比如我们对某个DOM元素进行添加和删除操作,这个不能同时进行,应该先添加,后删除。
这样也会有问题:如果JS执行时间过长,会造成页面渲染不连贯,导致页面渲染加载阻塞的感觉
为了解决这个问题,利用多喝CPU的计算能力,HTML5提粗Web Worker标准,允许JavaScript脚本创建多个线程,于是就有了同步和异步。
(2)同步和异步
1.同步
前一个任务结束后再执行后一个任务,程序的执行与任务的排列顺序是一致的、同步的。
该怎么理解呢?
就像做饭的同步做法:我们要烧水做饭,等水开了(10分钟之后),再去切菜,炒菜,一步一步来。
2.异步
在执行这个任务的同时,也在执行别的任务。
再来拿做饭打比方:在烧水的同时,我们来切菜,炒菜。
简单以一个案例来体验一下JS的执行过程:
console.log(1);
setTimeout(function () {console.log(3);
}, 1000);
console.log(2);
执行结果是:
由此可以看出,现在的JS可以同时执行任务,也就是可以异步执行
(3)同步任务
同步任务都在主线程是执行,形成一个执行栈
(4)异步任务
JS的异步任务是通过回调函数实现的
异步任务有三种类型:
- 普通事件:如click,resize等
- 资源加载:如load,error等
- 定时器:包括setInterval,setTimeout等
异步任务相关回调函数添加到任务队列中(任务队列也称为消息队列)
(5)JS执行机制
1.先执行执行栈中的同步任务
2.异步任务(回调函数)放入任务队列中
3.一旦执行栈中的同步任务完成,按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行
案例:来一个练习题试试,像下面这个代码该怎么执行呢?究竟是1 2 3还是1 3 2呢?
console.log(1);
setTimeout(function () {console.log(3);
}, 0);
console.log(2);
居然还是1 2 3,,看来这个是一个同步任务,它会形成一个执行栈
但是普通的同步任务只会产生1 2 3的序列,而setTimeout属于异步任务的定时器类型,它会产生一个任务队列
按照执行机制来看,先执行执行栈中的同步任务,先执行
console.log(1);
遇见了异步任务
setTimeout(fn(), 0);
把异步任务放入任务队列中,不执行,执行完执行栈里的同步任务后再执行,最后的输出就是我们看见的1 2 3
那如果有多个异步任务该怎么执行呢?我们来看下面这段代码
console.log(1);
document.onclick = function () {console.log('click');
}
console.log(2);
setTimeout(function () {console.log(3);
}, 1000);
里面的执行过程为:
其中document.onclick那个只有再鼠标点击后才会放入任务队列,setTimeout这个只有事件到了才会放入任务队列,也就是图中的console.log(3) ,执行完就会清空任务队列
由于主线程不断的重复获得任务、执行任务、在获取任务、再执行,所以这种机制被称为事件循环(even lop)
二、location对象
(1)location对象
window对象给我们提供了一个location属性用于获取或设置窗体的URL,并且可以用于解析URL。因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象。
(2)URL
统一资源定位符(Uniform Resource Locator,URL)是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器一个怎么处理它。
URL的一般语法格式为:
protocol://host[:port]/path/[?query]#fragment
http://www.itcast.cn/index.html?name=andy&age=18#link
组成 | 说明 |
---|---|
protocol | 通信协议,常用的http,ftp,maito等 |
host | 主机(域名) www.itheima.com |
port | 端口号(可选),省略时使用方案的默认端口,如http的默认端口为80 |
path | 路径,由领或多个'.'符号隔开的字符串,一般用来表示主机上的一个目录或文件地址 |
query | 参数,以键值对的形式,通过&符号分隔开来 |
fragment | 片段,#后面内容,常见于链接、锚点 |
(3)location对象的属性
location对象属性 | 返回值 |
---|---|
location.href | 获取或者设置整个URL |
location.host | 返回主机(域名) www.itheima.com |
location.port | 返回端口号,如果未写则返回空字符串 |
location.pathname | 返回路径 |
location.search | 返回参数 |
location.hash | 返回片段 |
敲重点!!!href和search要重点记住
来做一个案例:5秒后跳转页面
手动跳转:
<button>点击</button>
var btn = document.querySelector('button');
btn.addEventListener('click', function () {location.href = 'http://www.itcast.cn';
})
直接输出location.href可以得到该页面的整个URL,赋值可以去往另一个页面
主播主播,手动跳转还是太累了,有没有更强势的跳转方式?
有的有的,有一个自动跳转的方法
先建立一个空的div盒子
<div></div>
然后写JS,采用定时器实现5s后跳转页面
var div = document.querySelector('div');
var timer = 5;
function fn() {div.innerHTML = '您将在' + timer + '秒之后跳转到首页';timer--;
}
fn();
setInterval(function () {if (timer == 0) {location.href = 'http://www.itcast.cn';}else {fn();}
}, 1000)
案例:获取URL参数数据
来练习一下数据在不同页面中的传递
新建一个文件夹,将我们要建立我们这两个页面
然后在login.html中使用表单,来将数据传输到index.html里
<form action="index.html">用户名<input type="text" name="uname"><input type="submit" value="登录">
</form>
在这个界面里输入123
在index这里我们就有了123这个信息
也就是要用?后面的那一串信息
我们可以用location.search得到?uname=123
但是我们不需要?,则我们用substr去掉
var params=location.search.substr(1);
然后再利用=分割键和值,也就是split('=')
var arr=params.split('=');
再把数据写入div中
var div = document.querySelector('div');
div.innerHTML = arr[1] + '欢迎您';
这样就能把数据传到另一个页面上啦
(4)location对象的方法
location对象方法 | 返回值 |
---|---|
location.assign() | 跟href语言,可以跳转页面(也称为重定向页面) |
location.replace() | 替换当前页面,因为不记录李四,所以不能后退界面 |
location.reload() | 程序加载页面,相当于刷新按钮或者f5,如果参数为true,强制刷新(Ctrl+f5) |
1.location.assign()
var btn = document.querySelector('button');
btn.addEventListener('click', function () {location.assign('http://www.itcast.cn');
})
记录浏览历史,可以实现后退功能
2.location.replace()
var btn = document.querySelector('button');
btn.addEventListener('click', function () {location.replace('http://www.itcast.cn');
})
不记录浏览历史,不可以实现后退功能
3.location.reload();
location.reload();
重新加载,也就是刷新,如果参数是true,则强制刷新
(5)navigator对象
navigator对象包含有关浏览器的信息,有很多属性,最常用的是userAgent,该属性可以返回有客户机发送服务器的user—-agent头部的值。
下面前端代码可以判断用户那个中断打开页面,实现跳转
if(navigator.userAgent.match(/phone|pad|pod|iPod|ios|ipad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowserNG|WebOS|Symbian|Windows Phone)/i))) {window.location.href = "";//手机
}
else {window.location.href = "";//电脑
}
(6)history对象
window对象给我们提供了一个history对象,与浏览器历史记录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL。
history对象方法 | 作用 |
---|---|
back() | 可以后退功能 |
forward() | 前进功能 |
go(参数) | 前进后退功能,如果参数是1,前进一个页面,如果参数是-1,后退一个页面 |
1.back()
模拟后退功能
var btn = document.querySelector('button');
btn.addEventListener('click', function () {history.back()
})
2.forward()
模拟前进功能
var btn = document.querySelector('button');
btn.addEventListener('click', function () {history.forward()
})
3.go()
模拟前进和后退
前进:
var btn = document.querySelector('button');
btn.addEventListener('click', function () {history.go(1)
})
后退:
var btn = document.querySelector('button');
btn.addEventListener('click', function () {history.go(-1)
})
history对象一般在实际开发中比较少用,但是会在一下办公系统中见到。