1. 作用域
1.1 局部作用域
1.2 全局作用域
1.3 作用域链
1.4 JS垃圾回收机制(闭包做铺垫)
1.4.1 什么是垃圾回收机制
1.4.2 内存的声明周期
1.4.3 垃圾回收的算法说明
1.4.3.1 引用计数法
1.4.3.2 标记清除法
1.5 闭包
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>闭包</title>
</head>
<body>
<script>//闭包的简单写法// function outer(){// let a=10// function inner(){// console.log(a)// }// inner()// }// outer()//闭包的常用形式,函数可以访问使用函数内部的变量function outer() {let num = 10function inner() {console.log(num)}// inner()return inner //返回函数中的值,相当于返回外部函数中的局部变量}// outer()===inner===function inner()// const fun=function inner(){}const fun=outer() //此时的fun是个函数fun() //调用函数//闭包的应用,统计函数调用的次数let i=0function fn(){i++console.log(`函数被调用了${i}次`)}
</script>
</body>
</html>
1.6 变量提升
2. 函数进阶
2.1 函数提升
2.2 函数参数
2.2.1 动态参数
2.2.2 剩余参数
2.2.3 展开运算符
2.3 箭头函数(重要)
2.3.1 基本语法
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>箭头函数</title>
</head>
<body>
<script>//语法1.基本写法//普通函数const fn1=function(){console.log("普通函数")}fn1()//箭头函数const fn2=()=>{console.log("箭头函数")}fn2()//语法2.只有一个参数,可以省略小括号//普通函数const fn3=function(x){return x+x}console.log(fn3(1)) //2//箭头函数const fn4=x=>{return x+x}console.log(fn4(2)) //4//语法3.如果函数体只有一行代码,可以写到一行上,并且无需写return,直接返回值//普通函数const fn5=function(x,y){return x+y}console.log(fn5(1, 2)); //3//箭头函数const fn6=(x,y)=>x+yconsole.log(fn6(2, 3)); //5//语法4.加括号的函数体返回对象字面量表达式const fn7=uname=>({name:uname})console.log(fn7("chenchen"))
</script></body>
</html>
2.3.2 箭头函数参数
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>箭头函数-参数</title>
</head>
<body>
<script>const getSum=(...args)=>{let sum=0for(let i=0;i<args.length;i++){sum+=args[i]}return sum //函数体有多行代码需要return}console.log(getSum(1, 2, 3)); //6
</script>
</body>
</html>
2.3.3 箭头函数this
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>箭头函数-this</title><style>button {width: 100px;height: 50px;}</style>
</head>
<body>
<button>点击</button>
<script>//获取对象const btn = document.querySelector("button")console.log(this) //window//箭头函数const sayHi = () => {console.log(this) //箭头函数此处为window}//箭头函数:this指向了windowbtn.addEventListener('click',()=>{console.log(this)})//普通函数,this指向了DOM对象btn.addEventListener('click', function (){console.log(this)})
</script>
</body>
</html>
3. 解构赋值(重要)
3.1 数组结构
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>解构赋值</title>
</head>
<body>
<script>// const arr=[100,80,60]// 数组解构 赋值// const max=arr[0]// const avg=arr[1]// const min=arr[2]// const [max,avg,min]=arrconst [min,avg,max]=[60,80,100]console.log(max) //100console.log(min) //60console.log(avg) //80// 交换变量值,注意第二个变量的后面一定要加上分号;let a=1let b=2;[a,b]=[b,a]console.log(a,b)
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>必须加分号的两种情况</title>
</head>
<body>
<script>//1.立即执行函数要加分号(function (){})();(function (){})();//2.使用数组的时候要加分号const arr=[1,2,3]const str="pink"arr.map(function(item){console.log(item)})//在开头是数组的语句之前的语句后面一定要加上一个分号,表示前面语句的结束;[4,5,6].map(function (item){console.log(item)})
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>数组结构赋值</title>
</head>
<body>
<script>//需求一const pc = ['海尔', '联想', '小米', '方正'];[hr, lx, mi, fz] = pcconsole.log(hr)console.log(lx)console.log(mi)console.log(fz)// 需求二function getValue() {return [100, 60]};[max, min] = getValue()console.log("max:" + max)console.log("min:" + min)
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>解构赋值(细节)</title>
</head>
<body>
<script>const [a,b,c,d]=[1,2,3]console.log(a) //1console.log(b) //2console.log(c) //3console.log(d) //undefinedconst [e,f,g]=[1,2,3,4]console.log(e) //1console.log(f) //2console.log(g) //3
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>解构赋值(细节)</title>
</head>
<body>
<script>//1.变量多、数值少const [a, b, c, d] = [1, 2, 3]console.log(a) //1console.log(b) //2console.log(c) //3console.log(d) //undefined//2.变量少、数值多const [e, f, g] = [1, 2, 3, 4]console.log(e) //1console.log(f) //2console.log(g) //3//3.剩余参数,变量少、数值多const [h, i, j, ...l] = [1, 2, 3, 4, 5, 6]console.log(h) //1console.log(i) //2console.log(j) //3console.log(l) //[4,5,6] 真数组//4.防止undefined传递const [m = 0, n = 0, o = 0] = [1, 2]console.log(m) //1console.log(n) //2console.log(o)//5.按需导入赋值const [p, q, , s] = [1, 2, 3, 4]console.log(p) //1console.log(q) //2console.log(s) //4//6.多维数组解构const [t,u,v,[w,[x,y]]]=[1,2,3,[4,[5,6]]]console.log(t)console.log(u)console.log(v)console.log(w)console.log(x)console.log(y)
</script>
</body>
</html>
3.2 对象结构
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>对象结构</title>
</head>
<body>
<script>//1.对象解构语法// const obj={uname:"chenchen",age:18}// const {uname, age} = {uname: "chenchen", age: 18}// 等价于:const uname=obj.uname// const age=obj.age//要求属性名和变量名保持一致// console.log(uname)// console.log(age)//对象解构的变量名,可以重新命名,旧变量名:新变量名// const {uname: u, age: a} = {uname: "chenchen", age: 19}// console.log(u)// console.log(a)//2.解构数组对象const pig = [{uname: "佩奇",age: 18}]const [{uname,age}]=pigconsole.log(uname)console.log(age)
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>对象解构ex</title>
</head>
<body>
<script>//需求1const pig={name:"佩奇",age:16}const {name,age}=pigconsole.log(name)console.log(age)//需求2const {name:uname}=pigconsole.log(uname)//需求3const goods=[{goodsName:"小米",price:1999}]const [{goodsName,price}]=goodsconsole.log(goodsName)console.log(price)
</script>
</body>
</html>
3.3 多级对象解构
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>多级对象解构</title>
</head>
<body>
<script>/* const pig = {name: '佩奇', family: {monther: "猪妈妈", father: "猪爸爸", sister: "乔治"}, age: 6}const {name, family: {monther, father, sister}, age} = pigconsole.log(name)console.log(monther)console.log(father)console.log(sister)console.log(age)*//*const pig = [{name: '佩奇', family: {monther: "猪妈妈", father: "猪爸爸", sister: "乔治"}, age: 6}]const [{name, family: {monther, father, sister}, age}] = pigconsole.log(name)console.log(monther)console.log(father)console.log(sister)console.log(age)*/const msg = {"code": 200,"msg": "获取新闻列表成功","data": [{"id": 1,"title":"5G商用","count":5},{"id":2,"title":"国际","count":4},{"id":3,"title":"乌克兰","count":3},]}//需求1:请将以上msg对象,采用对象解构的方式,只选出data方面后面使用渲染页面/*const {data}=msgconsole.log(data)*///需求2:上面msg是后台传递过来的数据,我们需要把data选出当作参数传递给函数/*const {data}=msg// console.log(data)function render(arr){console.log(arr)}render(data)*/function render({data}){console.log(data)}render(msg)//需求3:为了防止msg里面的data名字混淆,要求渲染函数里面的数据名改为myData/* const {data:myData}=msgconsole.log(myData)*//* function render({data:myData}){console.log(myData)}render(msg)*/
</script>
</body>
</html>
4.foreach遍历数组
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>foreach遍历数组</title>
</head>
<body>
<script>//foreach主要是遍历const arr=['a','b','c']arr.forEach(function (item,index){console.log(item) //数组元素:a,b,cconsole.log(index) //索引号:0,1,2})
</script>
</body>
</html>
5.筛选数组filter()方法
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>筛选数组filter()方法</title>
</head>
<body>
<script>//筛选数组中大于60的元素const score=[10,20,30,50,60,80,90,79]const re=score.filter(function(item){return item>=60})console.log(re)
</script>
</body>
</html>
6.深入对象
6.1 创建对象的三种方式
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>创建对象的三种方式</title>
</head>
<body>
<script>//方式1/*const obj1={"uname":"chenchen"}console.log(obj1.uname)*///方式2const obj2=new Object()obj2.uname='cc'console.log(obj2)const obj3=new Object({uname:'yy'})console.log(obj3)
</script>
</body>
</html>
6.2 构造函数
6.3 实例成员&静态成员
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>实例成员&静态成员</title>
</head>
<body>
<script>//实例成员和静态成员//1.实例成员:实例对象上的属性和方法属于实例成员/*function Pig(name) {this.name = name}const peiqi = new Pig("佩奇")const qiaozhi = new Pig("乔治")peiqi.name = "小猪佩奇" //实例属性peiqi.sayHi = () => { //实例方法console.log("hello")}console.log(peiqi)console.log(qiaozhi)console.log(peiqi===qiaozhi)*///2.静态成员:构造函数上的属性和方法属于静态成员function Pig(name){this.name=name}Pig.eyes=2 //静态属性Pig.sayHi=function (){ //静态方法console.log(this)}Pig.sayHi()console.log(Pig.eyes)</script>
</body>
</html>
7.内置构造函数
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>基本包装类型</title>
</head>
<body>
<script>const arr="chenchen"console.log(arr.length)const num=12console.log(num.toFixed(2)) //保留两位小数
</script>
</body>
</html>
7.1 Object
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>Object静态方法</title>
</head>
<body>
<script>const o={name:"cc",age:18}//1.获取所有的属性名,Object.keys(对象名)console.log(Object.keys(o)) //['name', 'age']//2.获得所有的属性值console.log(Object.values(o)) //['cc', 18]//3.对象的拷贝/*const oo={}Object.assign(oo,o)console.log(oo)*/Object.assign(o,{gender:'女'})console.log(o)
</script>
</body>
</html>
7.2 Array
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>内置构造函数-Array</title>
</head>
<body>
<script>//普通创建数组const arr=new Array(1,2,3)console.log(arr)//reduce()const count=arr.reduce((prev,item)=>(prev+item))console.log(count)
</script>
</body>
</html>
7.3 String
7.4 Number
8.编程思想
8.1 面向过程思想
8.2 面向对象思想
9.构造函数
10.原型
10.1 什么是原型
公共的属性写到构造函数中,公共的方法写到原型对象中
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>原型</title>
</head>
<body>
<script>//构造函数,公共的属性和方法 封装到Star构造函数中//1.公共的属性写到构造函数里function Star(uname,age){this.uname=unamethis.age=age}//2.公共的方法写到原型对下个身上Star.prototype.sing=function(){console.log('唱歌')}
// 创建对象var ldh = new Star('刘德华',55)var zxy = new Star('张学友',58)
// 调用ldh.sing()zxy.sing()console.log(ldh===zxy)
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>构造函数和原型this指向</title>
</head>
<body>
<script>let thatfunction Star(uname){that=thisthis.uname=uname}//实例对象 ldh//构造函数里面的this就是实例对象 ldhconst ldh=new Star('刘德华')console.log(that===ldh)
// 原型对象里面的函数this指向的还是实例对象ldhStar.prototype.sing=function(){that=thisconsole.log('唱歌')}
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>原型-数组拓展方法</title>
</head>
<body>
<script>//自己定义 数组拓展方法,求和和最大值//1.定义的方法,任何一个数组实例对象中都可以进行使用//2.自定义的方法写到,数组.prototype身上//(1)最大值const arr=[1,2,3]Array.prototype.max=function(){//展开运算符return Math.max(...this)//原型函数中的this指向实例对象arr}//(2)最小值Array.prototype.min=function(){//展开运算符return Math.min(...this)//原型函数中的this指向实例对象arr}//(3)求和Array.prototype.sum=function(){return this.reduce((prev,index)=>prev+index,0)}console.log("最大值:"+arr.max())console.log("最大值:"+[2,3,4,5,6].max())console.log("最小值:"+arr.min())console.log("最小值:"+[2,3,5,4,6,7].min())console.log("求和:"+arr.sum())console.log("求和:"+[2,3,4,5,6,7].sum())//const arr=new Array(1,2)//console.log(arr)
</script>
</body>
</html>
10.2 constructor属性
使用该属性可以找到实例所属的构造函数
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1.0"><title>constructor属性</title>
</head>
<body>
<script>//constructor 构造函数function Star(){}// const ldh=new Star()// console.log(Star.prototype.constructor===Star)Star.prototype={sing: function(){console,log("唱歌")},dance:function(){console.log("跳舞")},}
</script>
</body>
</html>
10.3 对象原型
对象都会有一个属性_proto_指向构造函数的prototype原型对象,之所以可以使用构造函数prototype原型对象的属性和方法,就是因为有了_proto_对象原型的存在。
10.4 原型继承
10.5 原型链
11.深浅拷贝
11.1 浅拷贝
11.2 深拷贝
11.2.1 通过递归实现深拷贝
11.2.2 lodash/cloneDeep
11.2.3 通过JSON.stringify()实现
12.异常处理
12.1 throw抛异常
12.2 try/catch捕获异常
12.3 debugger
13.处理this
13.1 this指向
13.1.1 普通函数this指向
13.1.2 箭头函数this指向
13.2 改变this
13.2.1 call() (了解)
13.2.2 apply() (理解)
13.2.3 bind() (重点)
14.性能优化
14.1 防抖
14.2 节流
15.节流综合案例