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 = 10
function inner() {
console.log(num)
}
// inner()
return inner //返回函数中的值,相当于返回外部函数中的局部变量
}
// outer()===inner===function inner()
// const fun=function inner(){}
const fun=outer() //此时的fun是个函数
fun() //调用函数
//闭包的应用,统计函数调用的次数
let i=0
function 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+y
console.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=0
for(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指向了window
btn.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]=arr
const [min,avg,max]=[60,80,100]
console.log(max) //100
console.log(min) //60
console.log(avg) //80
// 交换变量值,注意第二个变量的后面一定要加上分号;
let a=1
let 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] = pc
console.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) //1
console.log(b) //2
console.log(c) //3
console.log(d) //undefined
const [e,f,g]=[1,2,3,4]
console.log(e) //1
console.log(f) //2
console.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) //1
console.log(b) //2
console.log(c) //3
console.log(d) //undefined
//2.变量少、数值多
const [e, f, g] = [1, 2, 3, 4]
console.log(e) //1
console.log(f) //2
console.log(g) //3
//3.剩余参数,变量少、数值多
const [h, i, j, ...l] = [1, 2, 3, 4, 5, 6]
console.log(h) //1
console.log(i) //2
console.log(j) //3
console.log(l) //[4,5,6] 真数组
//4.防止undefined传递
const [m = 0, n = 0, o = 0] = [1, 2]
console.log(m) //1
console.log(n) //2
console.log(o)
//5.按需导入赋值
const [p, q, , s] = [1, 2, 3, 4]
console.log(p) //1
console.log(q) //2
console.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}]=pig
console.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>
//需求1
const pig={name:"佩奇",age:16}
const {name,age}=pig
console.log(name)
console.log(age)
//需求2
const {name:uname}=pig
console.log(uname)
//需求3
const goods=[{
goodsName:"小米",
price:1999
}]
const [{goodsName,price}]=goods
console.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} = pig
console.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}] = pig
console.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}=msg
console.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}=msg
console.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,c
console.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)*/
//方式2
const 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=12
console.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=uname
this.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 that
function Star(uname){
that=this
this.uname=uname
}
//实例对象 ldh
//构造函数里面的this就是实例对象 ldh
const ldh=new Star('刘德华')
console.log(that===ldh)
// 原型对象里面的函数this指向的还是实例对象ldh
Star.prototype.sing=function(){
that=this
console.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.节流综合案例