# Window对象
# BOM
BOM(Browser Object Model ) 是浏览器对象模型
window 是浏览器内置中的全局对象,我们所学习的所有 Web APIs 的知识内容都是基于 window 对象实现的
window 对象下包含了 navigator、location、document、history、screen 5个属性,即所谓的 BOM (浏览器对象模型)
- navigator对象:包含有关浏览器的信息,如名称,版本和系统等
- location对象:包含当前网页文档的URL信息
- document对象:HTML 文档
- history对象:包含浏览器窗口访问过的URL信息
document 是实现 DOM 的基础,它其实是依附于 window 的属性。
注:依附于 window 对象的所有属性和方法,使用时可以省略 window
# 定时器-延时函数
JavaScript 内置的一个用来让代码延迟执行的函数,叫 setTimeout
语法:
setTimeout(回调函数, 等待的毫秒数)
setTimeout 仅仅只执行一次,所以可以理解为就是把一段代码延迟执行, 平时省略window
清除延时函数:
let timer = setTimeout(回调函数, 等待的毫秒数) clearTimeout(timer)
结合递归函数可以使用setTimeout 实现 setInterval 一样的功能
- 递归函数:自己调用自己就是递归函数
- 递归函数容易造成死递归,一定要加退出条件
<div class="clock"></div>
<script>
let clock = document.querySelector('.clock')
function myInterval(){
let d = new Date();
clock.innerText = d.toLocaleString();
//延时任务,自调用
setTimeout(myInterval, 1000)
}
//启动定时任务
myInterval();
</script>
两种定时器对比:
setInterval 的特征是重复执行,首次执行会延时
setTimeout 的特征是延时执行,只执行 1 次
setTimeout 结合递归函数,能模拟 setInterval 重复执行
clearTimeout 清除由 setTimeout 创建的定时任务
# JS 执行机制
# JS 是单线程
JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事。这是因为 Javascript 这门脚本语言诞生的使命所致——JavaScript 是为处理页面中用户的交互,以及操作 DOM 而诞生的。比如我们对某个 DOM 元素进行添加和删除操作,不能同时进行。 应该先进行添加,之后再删除。
单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务。这样所导致的问题是: 如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。
# 同步和异步
为了解决这个问题,利用多核 CPU 的计算能力,HTML5 提出Web Worker 标准,允许JavaScript 脚本创建多个线程。于是,JS 中出现了同步和异步。
同步
- 前一个任务结束后再执行后一个任务,程序的执行顺序与任务的排列顺序是一致的、同步的。比如做饭的同步
- 做法:我们要烧水煮饭,等水开了(10分钟之后),再去切菜,炒菜。
异步
你在做一件事情时,因为这件事情会花费很长时间,在做这件事的同时,你还可以去处理其他事情。比如做饭的异步做法,我们在烧水的同时,利用这10分钟,去切菜,炒菜。
他们的本质区别: 这条流水线上各个流程的执行顺序不同。
# 同步任务和异步任务
同步任务
- 同步任务都在主线程上执行,形成一个执行栈。
异步任务
JS 的异步是通过回调函数实现的。
一般而言,异步任务有以下三种类型::
- 普通事件,如 click、resize 等
- 资源加载,如 load、error 等
- 定时器,包括 setInterval、setTimeout 等
异步任务相关添加到任务队列中(任务队列也称为消息队列)。
# JS 执行机制
(1)先执行执行栈中的同步任务。
(2)异步任务放入任务队列中。
(3)一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环( event loop)。
- 大白话: 在任务执行时,我们会把所有的任务分为两类:一类叫同步任务,同步任务在主线程上执行,形成一个执行栈,执行栈里的任务先执行。另一类叫异步任务,异步任务是通过回调函数实现的,一般有三种类型:普通事件、资源加载、定时器等。异步任务会被添加到任务队列中。当执行栈里的任务全部执行完毕后,系统会按异步任务中的执行顺序读取任务队列中的异步任务,被读取的异步任务会结束等待状态而进入到执行栈,然后开始执行。
# location对象
location 的数据类型是对象,它拆分并保存了 URL 地址的各个组成部分
常用属性和方法:
href 属性获取完整的 URL 地址,对其赋值时用于地址的跳转
//可以得到当前文件URL地址 console.log(location.href) //可以通过js方式跳转到目标地址 location.href = 'http://www.baidu.com'
search 属性获取地址中携带的参数,符号 ?后面部分
console.log(location.search)
hash 属性获取地址中的哈希值,符号 # 后面部分
console.log(location.hash)
- 后期vue路由的铺垫,经常用于不刷新页面,显示不同页面,比如 网易云音乐
reload 方法用来刷新当前页面,传入参数 true 时表示强制刷新
<button>点击刷新<button> <script> let btn = document.querySelector('button') btn.addEventListener('click', function(){ //强制刷新,类似于ctrl+f5 location.reload(true) }) </script>
# navigator对象
navigator的数据类型是对象,该对象下记录了浏览器自身的相关信息
常用属性和方法:
通过 userAgent 检测浏览器的版本及平台
// 检测 userAgent(浏览器信息) !(function () { const userAgent = navigator.userAgent // 验证是否为Android或iPhone const android = userAgent.match(/(Android);?[\s\/]+([\d.]+)?/) const iphone = userAgent.match(/(iPhone\sOS)\s([\d_]+)/) // 如果是Android或iPhone,则跳转至移动站点 if (android || iphone) { location.href = 'http://m.itcast.cn' } })()
# histroy对象
history 的数据类型是对象,该对象与浏览器地址栏的操作相对应,如前进、后退、历史记录等
常用的属性和方法:
history对象方法 作用 back() 可以后退功能 forward() 前进功能 go(参数) 前进后退功能 参数如果是1前进1个页面,如果是-1后退1个页面 例如:
qianjin.addEventListener('click', function(){ history.forward() //history.go(1) }) houtui.addEventListener('click', function(){ history.back() //history.go(-1) })
history 对象一般在实际开发中比较少用,但是会在一些 OA 办公系统中见到。
# 本地存储
# 本地存储特性
- 随着互联网的快速发展,基于网页的应用越来越普遍,同时也变的越来越复杂,为了满足各种各样的需求,会经常性在本地存储大量的数据,HTML5规范提出了相关解决方案。
- 数据存储在用户浏览器中
- 设置、读取方便、甚至页面刷新不丢失数据
- 容量较大,sessionStorage和localStorage约 5M 左右
# localStorage
生命周期永久生效,除非手动删除 否则关闭页面也会存在
可以多窗口(页面)共享(同一浏览器可以共享)
以键值对的形式存储使用
//存储数据: localStorage.setItem(key, value) //获取数据: localStorage.getItem(key) //删除数据: localStorage.removeItem(key)
- 注意:字符串要放在''内
本地查看,以谷歌浏览器为例:右键单击-检查-Application-Local Storage
存储复杂数据类型存储
本地只能存储字符串,无法存储复杂数据类型.需要将复杂数据类型转换成JSON字符串,再存储到本地
JSON.stringify(复杂数据类型)
- 将复杂数据转换成JSON字符串 存储 本地存储中
let obj = { uname: '小苏同学', age: 18, address: '沈阳师范大学' } localStorage.setItem('obj', JSON.stringify(obj))
JSON.parse(JSON字符串)
- 将JSON字符串转换成对象 取出 时候使用
console.log(JSON.parse(localStorage.getItem('obj')))
# sessionStorage(了解)
生命周期为关闭浏览器窗口
在同一个窗口(页面)下数据可以共享
以键值对的形式存储使用
用法跟localStorage 基本相同
# 自定义属性
固有属性:
- 标签天生自带的属性 比如class id title等, 可以直接使用点语法操作
自定义属性:
由程序员自己添加的属性,在DOM对象中找不到, 无法使用点语法操作,必须使用专门的API
element.setAttribute('属性名', '属性值') // 设置自定义属性
<div id='mydiv' class='nav'></div> <!--创建属性时,对于标签中已存在的属性,则会进行赋值操作,注意class比较特殊,它对应的class而不是className--> let div = document.querySelector('#mydiv') console.log(div.setAttribute('class','footer')); //<div id='mydiv' class='footer'>
element.getAttribute('属性名') // 获取自定义属性
<div id='mydiv'></div> let div = document.querySelector('#mydiv') console.log(div.getAttribute('id')); //mydiv
element.removeAttribute('属性名') // 删除自定义属性
<div id='mydiv' index='1'></div> let div = document.querySelector('#mydiv') console.log(div.removeAttribute('index'));
自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。
但是有些自定义属性很容易引起歧义,不容易判断是元素的内置属性还是自定义属性,H5因此给我们新增了自定义属性
H5规定自定义属性
data-
开头作为属性名并且赋值data-自定义属性:
传统的自定义属性没有专门的定义规则,开发者随意定值,不够规范,所以在html5中推出来了专门的data-自定义属性 在标签上一律以
data-
开头在DOM对象上一律以dataset对象方式获取
<div class="box" data-id="10"></div>
<script>
let box = document.querySelector('.box')
console.log(box.dataset.id) //10
</script>
可以通过
element.dataset.自定义属性名
或者element.dataset['自定义属性名']
获取自定义属性(有严重的兼容性问题 ie11才开始支持),并且只支持data-
开头的- dataset是一个集合,里面存放了所有以data开头的自定义属性
<div id='mydiv' data-index='1'></div> 例如:获取index属性的值 let div = document.querySelector('#mydiv') div.dataset.index div.dataset['index']
如果自定义属性中有多个 - 连接的单词,我们获取的时候采取驼峰命名法
<div id='mydiv' data-list-name='su'></div> let div = document.querySelector('#mydiv') div.dataset.listName div.dataset['listName']
# 正则表达式
# 概念
正则表达式(Regular Expression)是用于匹配字符串中字符组合的模式。在 JavaScript中,正则表达式也是对象
通常用来查找、替换那些符合正则表达式的文本,许多语言都支持正则表达式。
正则表达式在 JavaScript中的使用场景:
例如验证表单:用户名表单只能输入英文字母、数字或者下划线, 昵称输入框中可以输入中文(匹配)
- 比如用户名: /^[a-z0-9_-]{3,16}$/
过滤掉页面内容中的一些敏感词(替换)
从字符串中获取我们想要的特定部分(提取)等 。
# 语法
(1)定义规则 (2)查找
JavaScript 中定义正则表达式的语法有两种,我们先学习其中比较简单的方法:
定义正则表达式语法:
let 变量名 = /表达式/
- 其中 / / 是正则表达式字面量
- 比如:
let reg = /前端/
判断是否有符合规则的字符串:
test() 方法 用来查看正则表达式与指定的字符串是否匹配
语法:
regObj.test(被检测的字符串)
比如:
let str = '前端开发, web前端, 软件开发, 软件测试' let reg = /前端/ let re = reg.test(str) console.log(re) //true
- 如果正则表达式与指定的字符串匹配 ,返回true,否则false
检索(查找)符合规则的字符串:
exec() 方法 在一个指定字符串中执行一个搜索匹配
语法:
regObj.exec(被检测的字符串)
比如:
let str = '前端开发, web前端, 软件开发, 软件测试' let reg = /前端/ let re = reg.exec(str) console.log(re) //返回的是个数组
- 如果匹配成功,exec() 方法返回一个数组,否则返回null
正则表达式检测查找 test方法和exec方法有什么区别?
- test方法 用于判断是否有符合规则的字符串,返回的是布尔值 找到返回true,否则false
- exec方法用于检索(查找)符合规则的字符串,找到返回数组,否则为null
# 元字符
普通字符:
- 大多数的字符仅能够描述它们本身,这些字符称作普通字符,例如所有的字母和数字。
- 也就是说普通字符只能够匹配字符串中与它们相同的字符。
元字符(特殊字符)
- 是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
- 比如,规定用户只能输入英文26个英文字母,普通字符的话 abcdefghijklm…..
- 但是换成元字符写法: [a-z]
- 是一些具有特殊含义的字符,可以极大提高了灵活性和强大的匹配功能。
参考文档:
- MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions
- 正则测试工具: http://tool.oschina.net/regex
为了方便记忆和学习,我们对众多的元字符进行了分类:
- 边界符(表示位置,开头和结尾,必须用什么开头,用什么结尾)
- 量词 (表示重复次数)
- 字符类 (比如 \d 表示 0~9)
(1)边界符
正则表达式中的边界符(位置符)用来提示字符所处的位置,主要有两个字符
边界符 说明 ^ 表示匹配行首的文本(以谁开始) $ 表示匹配行尾的文本(以谁结束) - 如果 ^ 和 $ 在一起,表示必须是精确匹配。 例如:^哈$ 匹配只能是 哈
(2)量词
量词用来 设定某个模式出现的次数
量词 说明 * 重复零次或更多次 + 重复一次或更多次 ? 重复零次或一次 {n} 重复n次 {n,} 重复n次或更多次 {n,m} 重复n到m次 例如:
/a*/ //代表a可以出现0次或更多次,a出现的次数n>=0 /a+/ //代表a至少出现1次或更多次,a出现的次数n>=1 /a?/ //代表a可以出现0次或1次,a出现的次数0||1 /a{3}/ //代表a至少连续出现3次,可以多次,不能少于3。如baaad、caaaav /^a{3}$/ //代表只能是aaa,开头结尾都是a,且连续出现3次 /^a{3}/ //代表a开头,且连续出现最少3次。如aaaa、aaab /a{3}$/ //代表a结尾,且连续出现最少3次。如aaaa、baaa /a{3,}/ //代表a至少连续出现3次或更多次。如scdaaaw、sdcaaaasd /a{3,6}/ //代表a至少连续出现3次或更多次 /^a{3,6}$/ //代表a至少连续出现3~6次
- 注意: 逗号左右两侧千万不要出现空格
[ ] 匹配字符集合
- 例如:[abc].test('abc')
- 后面的字符串只要包含 abc 中任意一个字符,都返回 true。
- []理解为只能存储1个字符,[abc]可以理解为abc中的任意一个字符,三选一,可以是a,可以是b,可以是c
- 例如:[abc].test('abc')
[ ] 里面加上 - 连字符
使用连字符 - 表示一个范围
console.log(/^[a-z]$/.test('c') //true
比如:
- [a-z] 表示 a 到 z 26个英文字母都可以
- [a-zA-Z] 表示大小写都可以
- [0-9] 表示 0~9 的数字都可以
认识下:
//腾讯QQ号: ^[1-9][0-9]{4,}$ //腾讯QQ号从10000开始 //中文验证: ^[\u4e00-\u9fa5]{2,8}$/ //日期格式: ^\d{4}-\d{1,2}-\d{1,2}
[ ] 里面加上 ^ 取反符号
- 比如:
- [^a-z] 匹配除了小写字母以外的字符
- 注意要写到中括号里面
- 比如:
. 匹配除换行符之外的任何单个字符
预定义:指的是某些常见模式的简写方式。
预定类 说明 \d 匹配0-9之间的任一数字,相当于[0-9] \D 匹配所有0-9以外的字符,相当于[^0-9] \w 匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_] \W 除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_] \s 匹配空格(包括换行符、制表符、空格符等),相当于[\t\r\n\v\f] \S 匹配非空格的字符,相当于[^\t\r\n\v\f]
# 修饰符
修饰符约束正则执行的某些细节行为,如是否区分大小写、是否支持多行匹配等
语法:
/表达式/修饰符
i 是单词 ignore 的缩写,正则匹配时字母不区分大小写
例如:
console.log(/a/i.test('a')) //true console.log(/a/i.test('A')) //true
g 是单词 global 的缩写,匹配所有满足正则表达式的结果
替换 replace 替换
语法:
字符串.replace(/正则表达式/, '替换的文本')
例如:
let str='小苏同学爱吃苹果' console.log(str.replace(/苹果/,'香蕉')) //小苏同学爱吃香蕉
扩展
for(){ break //退出循环 结束循环 continue //结束本次循环,继续下一次循环 }
function fn(){ return //有值便返回值,没有值便结束函数 }