JavaScript
一、文档对象模型 DOM
1、DOM树
文档【document】、元素element、节点node
2、事件基础
2.1、事件三要素
事件源、事件类型、事件处理函数
2.2、执行事件步骤
a、获取事件源 元素节点
b、注册事件
传统方式:
注册:事件源【元素】.onclick = function() {…}
解绑事件:元素.onclick = null
方法监听注册方式:元素.addEventListener(‘click’,function() {…})
解绑事件:元素.removeEventListener(type,listener,useCapture);
c、添加事件处理函数
3、事件对象
3.1、事件对象的常见属性和方法
e.target
返回触发事件的对象 标准
e.target返回的是触发事件的对象(点击了哪个元素返回哪个对象或元素);this返回的是绑定了事件的对象(元素);this约等于e.currentTarget。
e.srcElement
返回触发事件的对象 非标准 ie6、7、8使用
e.type
返回事件的类型 比如click、mouseover 不带on
e.cancelBubble
该属性阻止冒泡、非标准 ie6、7、8使用
e.returnValue
该属性阻止默认事件(默认行为) 非标准 ie6、7、8使用 比如不让链接跳转
e.preventDefault()
该属性阻止默认事件(默认行为) 标准 比如不让链接跳转
e.stopPropagation()
阻止冒泡 标准
3.2、鼠标事件对象
e.clientX
返回鼠标相对于浏览器窗口可视区的X坐标
e.clientY
返回鼠标相对于浏览器窗口可视区的Y坐标
e.pageX
返回鼠标相对于文档页面的X坐标
e.pageY
返回鼠标相对于文档页面的Y坐标
e.screenX
返回鼠标相对于电脑屏幕的X坐标
e.screenY
返回鼠标相对于电脑屏幕的Y坐标
3.3、键盘事件对象
键盘事件对象—keyCode:返回该键的ASCII值
4、DOM事件流
4.1、事件流概念
事件流描述的是从页面中接收事件的顺序。事件发生会在元素节点之间按照特定的顺序传播,这个传播过程就是DOM事件流。
4.2、事件捕获:从外到里【若子和父都有点击事件,那么点击父亲,只会执行父亲的回调,若点击儿子,先会执行父亲的,再执行儿子的】
4.3、事件冒泡:从里到外【若子和父都有点击事件,若点击父亲的,只会执行父亲的,若点击儿子的,会先执行儿子的,后执行父亲的】
事件冒泡应用:事件委托(代理、委派)
a、事件委派原理
不是每个子节点单独设置事件监听器,而是事件监听器设置在其父节点上,然后利用冒泡原理,通过e.target影响设置每个子节点。
b、事件委派作用
只操作了一次DOM,提高了程序的性能
二、BOM
1、BOM概念
BOM是浏览器对象模型,它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是windows。BOM由一系列相对对象的构成,并且每个对象都提供了很多方法和属性。
2、BOM构成
2.1、window
window对象是浏览器的顶级对象,它具有双重角色。
他是JS访问游览器窗口的一个接口
他是一个全局对象,定义在全局作用域中的变量、函数都会变成window对象的属性和方法。在调用的时候可以省略window,前面学习的对话框属于window对象方法,如alert()、prompt()等
windows对象的常见事件
窗口加载事件
概念
window.onload是窗口(页面)加载事件,当文档内容完全加载完成会触发该事件(包括图像、脚本文件、CSS文件等)。就调用的处理函数。
写法
window.onload = function() {…}
window.addEvebtListener(‘load’,function() {…})
注意
有了window.onload就可以把JS代码写到页面元素的上方,因为onload是等页面内容全部加载完毕,再去执行处理函数;
window.onload传统注册事件方式只能写一次,会以最后一个window.onload为准。
如果使用addEventListener则没有限制。
调整窗口大小事件
概念
调整窗口大小加载事件,当触发时就调用的处理函数。
写法
window.onresize = function () {…}
window.addEventListener(‘resize’,function() {…})
注意
只要窗口大小发生像素变化,就会触发这个事件
我们经常利用这个事件完成响应式布局。window.innerWidth当前屏幕的宽度。
定时器
setTimeout()【一次性】
设置定时器
window.setTimeout(调用函数,[延迟的毫秒数]);
注意
window可以省略
这个调用函数可以直接写函数,或者写函数名或者采取字符串‘函数名()’三种形式
间隔的毫秒数省略默认是0,如果写,必须是毫秒,表示过多长时间自动调用这个函数,一次性,不重复
因为定时器可能很多,所以我们经常给定时器赋值一个标识符。
清除定时器
window.clearTimeout(定时器名字);
setInterval()【可重复】
设置定时器
window.setInterval(调用函数,[延迟的毫秒数]);
注意
window可以省略
这个调用函数可以直接写函数,或者写函数名或者采取字符串‘函数名()’三种形式
间隔的毫秒数省略默认是0,如果写,必须是毫秒,表示每间隔多长时间自动调用这个函数
因为定时器可能很多,所以我们经常给定时器赋值一个标识符。
清除定时器
window.clearInterval(定时器名字);
2.2、document
2.3、location
概念
window对象给我们提供了一个location属性用于获取或者设置窗体的URL,并且可以解析URL,因为这个属性返回的是一个对象,所以我们将这个属性也称为location对象。
URL统一资源定位符是互联网上标准资源的地址,互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器该怎么处理他。
location对象的属性
location.href
获取或者设置整个URL
location.host
返回主机(域名)www.itheima.com
location.port
返回端口号 如果未写返回空字符串
location.pathname
返回路径
location.search
返回参数【问号后面的】
location.hash
返回片段 #后面内容 常见于链接、锚点
location对象方法
location.assign( )
跟href一样,可以跳转页面(也称为重定向页面),记录历史
location.replace( )
替换当前页面,因为不记录历史,所以不能后退页面
location.reload( )
重新加载页面,相当于刷新按钮或者f5 如果参数为true 强制刷新ctrl+f5
2.4、navigator
概念及作用
navigator对象包含有关浏览器的信息,他有很多属性,我们最常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值。下面前端代码可以判断用户用哪个终端打开页面,实现跳转。
2.5、screen
2.6、history
概念
window对象给我们提供了一个history对象,与浏览器历史记录进行交互。该对象中包含用户(在浏览器窗口中)访问过的URL。
方法
切换历史状态
history.forward( )
前进功能
history.back( )
可以后退功能
history.go(参数)
前进后退功能,如果参数是1 前进1个页面 如果是-1 后退1个页面
修改历史状态
history.pushState(state, title[, url])
history.replaceState(state, title[, url])
三、ECMAScript
1、变量
2、数据、数据类型
2.1、数据类型
基本类型、引用类型
2.2、类型检测
a、typeof 校验除null之外的基本类型
b、xxx instanceof constructor 适用于精准检测引用数据类型
可以正确判断对象的类型,用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上,object instanceof constructor,object为实例对象,constructor为构造函数
c、Object.prototype.toString.call()
调用该方法,统一返回格式“[object Xxx]”的字符串
d、typeof与instanceof区别
typeof会返回一个变量的基本类型,instanceof返回的是一个布尔值
instanceof 可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型
虽然可以判断基础数据类型(null 除外),但是引用数据类型中,除了function 类型以外,其他的也无法判断
2.3、数据类型转换
a、转换为字符串类型
变量.toString()
String(变量)
隐式转换:加号拼接字符串:【变量 + ‘’ 】
b、转换为数字类型
parseInt(变量):将string类型转换成整数数值型
parseFloat(变量):将string类型转换成浮点数数值型
Number(变量)
隐式转换:利用-、*、/【变量 – 0、变量 * 1 、变量 / 1】
c、转换为布尔类型
Boolean(变量):Boolean(‘true’)
3、运算符 运算符优先级
一级:小括号()
二级:一元运算符 ++ — !
三级:算术运算符 先乘除取余 后加减
四级:关系运算符 > >= < <=
五级:相等运算符 == != === !==
六级:逻辑运算符 先&& 后||
七级:赋值运算符 =
八级:逗号运算符 ,
4、流程控制
4.1、概念
流程控制就是来控制我们的代码按照什么顺序来执行
4.2、结构类型
a、顺序结构
顺序结构是程序中最简单的、最基本的流程控制,他没有特定的语法结构,程序会按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。
b、分值结构
分支结构由上到下执行代码的过程中,根据不同的条件,执行不同的路径代码(执行代码多选一的过程),从而得到不同的结果
例:if语句 、switch语句
c、循环结构
概念:在实际问题中,有许多具有规律性的重复操作,因此在程序中要完成这类操作就要重复执行某些语句。
例:for循环、while循环
continue与break:
continue用于跳出本次循环,继续下一次循环,执行i++
break用于跳出整个循环,循环结束
5、内置对象
Math、Date、String、Array
6、预解析
变量预解析
就是把所有的声明变量提升到当前作用域最前面,不提升赋值操作。
函数预解析
就是把所有的函数声明提升到当前作用域的最前面,不调用函数。
7、this指向
7.1、this指向分类
a、普通函数 指向window
b、构造函数
实例对象,原型对象里面的方法也指向实例对象
c、对象方法
该方法所属对象
注:若对象中的方法为普通函数写法吗,则this指向该方法所属对象,若为箭头函数,则this指向为window
d、事件绑定函数
绑定事件对象
e、定时器
window
f、立即执行函数
window
g、箭头函数
外层作用域中的this(且this指向不可改变)
7.2、改变函数内部this指向
a、
函数名称.call(this要指向的,传递的参数1,…)
调用函数,并改变this指向
b、
函数名.apply(this要指向的,[传递的参数1,…])
利用apply传递数组(伪数组),借助数学内置对象求数组最大值/最小值
c、
函数名.bind(this要指向的,传递的参数1,…)
不调用函数,但改变this指向,调用需要fn.bind(…)( )
8、ES6
8.1、箭头函数
a、不能使用 arguments(使用了会报错,没有arguments)
b、箭头函数应用
箭头函数适合与this无关的回调,比如定时器、数组的方法回调,不适合与this有关的回调,事件回调,对象的方法。
c、箭头函数的this是静态的,箭头函数 this 指向声明时所在作用域下 this 的值,且无法改变。箭头函数的this不指向本身,指向外层作用域中的this
d、箭头函数不能作为构造函数实例化
8.2、Set:集合【去重】(类似数组)
a、概念
ES6 提供了新的数据结构 Set(集合)(是一个对象类型)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』(…)和『for…of…』进 行遍历
b、集合的属性和方法
size:返回集合的元素个数
add增加一个新元素,返回当前集合(一次只能加一个)
delete删除一个元素,返回Boolean值
has 检测集合中是否包含某个元素,返回 boolean 值
clear 清空集合,返回 undefined
8.3、Map(类似于对象)
a、概念
ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是“键” 的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。若给map赋初始值,可以以数组形式,数组里面的也都为数组形式:const m = new Map([array(2),array(2)]);这样形成一个对象中包含两对键值对,第一个数组中前一个为键名,后一个为键值,第二个数组同理。
b、Map的属性和方法
size 返回 Map 的元素个数(键值对个数)
set 增加一个新元素,返回当前 Map
delete 删除键值对,返回boolean 值
get 返回键名对象的键值
has 检测 Map 中是否包含某个元素,返回 boolean 值
clear 清空集合,返回 undefined
8.4、Promise
a、概念
Promise 是 ES6 引入的异步编程的新解决方案。语法上 Promise 是一个构造函数, 用来封装异步操作并可以获取其成功或失败的结果。
b、构造Promise
new Promise((resolve,reject) => { resolve(‘成功‘) 或者 reject(’失败‘)})
c、方法
promise名称.then( ):
Promise名称.then((value) => {console.log(value),(reason) => {console.log(reason)}) [成功和失败的回调]
promise名称.catch( ):
promise名称.catch(reason => {console.log(reason)})[失败的回调]
Promise.allSettled([p1,p2,…]):
p1,p2…都是promise,不管p1、p2…是成功的还是失败的,promise.allSettled都是成功
Promise.all([p1,p2,…]):
p1,p2…都是promise,p1、p2…全部成功promise.allSettled才是成功,只要有一个失败,Promise.all([p1,p2,…])就是失败的
8.5、async await
async 和 await 两种语法结合可以让异步代码像同步代码一样
await:
await 必须写在 async 函数中
await 右侧的表达式一般为 promise 对象
await + 表达式返回的是 promise 成功的值
await 的 promise 失败了, 就会抛出异常, 需要通过 try…catch 捕获处理
8.6、可选链操作符
可选链操作符( ?. )允许读取位于连接对象链深处的属性的值,而不必明确验证链中的每个引用是否有效。?. 操作符的功能类似于 . 链式操作符,不同之处在于,在引用为空(nullish ) (null 或者 undefined) 的情况下不会引起错误,该表达式短路返回值是 undefined。与函数调用一起使用时,如果给定的函数不存在,则返回 undefined。
9、构造函数
9.1、构造函数创建
a、创建构造函数
b、创建实例对象 new Fn()
new的作用:
在内存中创建一个新的内存空间
让this指向这个新对象
执行构造函数里面的代码,给这个新对象添加属性和方法
返回新对象(所以构造函数不需要return)
9.2、原型及原型链
9.2.1、构造函数的原型:prototype【原型对象】
a、概念
每一个构造函数都有一个原型对象prototype,prototype也是对象,所以叫原型对象;prototype里面有构造函数挂载到prototype上的公有方法,还有一个constructor(用于指回该构造函数);这个prototype原型对象指向另一个原型对象(Object原型对象prototype)【因为只要是对象就有__proto__,而__proto__都指向某个prototype】
b、prototype内部构造
通过构造函数挂载到prototype上的公有方法
constructor:用于指回该构造函数
c、原型链:
d、原型对象prototype中的this指向
指向实例对象(谁调用指向谁)
9.2.2、实例对象的原型:__proto__【对象原型】 指向构造函数的原型对象
9.2.3、构造函数、实例对象、原型(构造函数原型、实例对象原型)联系
9.2.4、JS成员查找规则
当访问一个对象的属性或方法时,先在该实例对象身上查找(即构造函数身上)
若没有再查找它的原型对象prototype
若没有查找原型对象的原型对象(Object的原型对象)【通过该原型对象的__proto__】
若都有,则采取就近原则选择
10、面向对象【类】
在ES6中新增加了类的概念,可以使用class类抽取了对象的公共部分,它泛指某一大类(模板),对象特指某一个,通过类实例化一个具体的对象
10.1、创建类与实例对象
创建类 :
class name {
constructor(uname){
this.uname = uname;
}
sing() {
console.log(‘i am’ + this.uname)
}
}
创建实例:
var xx = new name(‘cara’);
10.2、类的构造
a、类constructor构造函数(属性)
constructor()方法是类的构造函数(默认方法),用于传递参数,返回实例对象,通过new生成实例对象后自动调用该方法,如果没有显示定义,类内部会自动创建constructor
b、方法
普通函数方法、构造函数方法
10.3、类的继承
a、语法
b、super关键字
在调用构造函数方法时,super可以充当传递参数的角色,要在子类的constructor中写,而且super必须放到子类this前面;当调用普通函数时,可以直接在子级的方法中(不要写在constructor里面)用super.父亲方法()来调用【super必须与extends搭配使用】super无需考虑父级中this的指向,而ES5中的调用父亲的构造函数方法需要考虑父级中this指向问题,需要用call等方法修改this指向后才能调用构造函数方法:Father.call(this[修改后的this指向,在子级中写一般是this(也就是子级自己)],参数1,…)
继承中的属性或者方法查找原则:就近原则。继承中,如果实例化子类输出一个方法,先看子类中有没有这个方法,如果有就先执行子类的;若没有,就去父类中查找,如果有就执行这个方法
10.4、构造函数实例化对象与类实例化对象对比(ES5与ES6对比)
a、创建的对比 构造函数与CLass
b、继承的对比 通过原型与关键字extends
10.5、类的注意点
在ES6中类没有变量提升,所以必须先定义类,才能通过实例化对象
this指向问题:constructor里面的this指向实例对象,方法里的this指向这个方法的调用者
类里面的共有属性和构造函数方法(普通函数方法不需要)一定要加this使用。
super要搭配extends一起用,super要写到子类的constructor中,而且必须放到子类this前面
继承中的属性或者方法查找原则: 就近原则。继承中,如果实例化子类输出一个方法,先看子类中有没有这个方法,如果有就先执行子类的;若没有,就去父类中查找,如果有就执行这个方法
11、闭包
11.1、产生的条件 使用了高阶函数
高阶函数:
高阶函数是对其它函数进行操作的函数,它接收函数作为参数或将函数作为返回值输出。
接收函数作为参数
将函数作为返回值输出
11.2、概念
闭包指有权访问另一个函数作用域中变量的函数。简单理解就是一个作用域可以访问另一个函数内部的局部变量。
11.3、作用 延伸了变量的作用范围
12、深拷贝、浅拷贝
只有引用数据类型有深浅拷贝之分,基本数据类型都是深拷贝
a、深拷贝:拷贝数据
b、浅拷贝:拷贝地址
13、JS执行机制
13.1、JS是单线程,也就是说,同一时间只能做一件事。
a、同步(按顺序来)
同步任务:同步任务都在主流程上执行,形成一个执行栈。
b、异步(同时进行)
异步任务:JS的异步是通过回调函数实现的。异步任务相关回调函数添加到任务队列中(任务队列也称消息队列)。一般而言,异步任务有三种类型:
普通事件,如click、resize等
资源加载,如load、error等
定时器,包括setTimeout、setInterval等。
13.2、JS执行机制–Event Loop
a、先执行执行栈中的同步任务;
b、异步任务(回调函数)放入任务队列中;
c、一旦执行栈中的所有同步任务执行完毕,系统会按次序取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
d、事件循环