javascript的作用域与函数进阶和解构

作用域

作用域

1
2
3
4
5
6
7
8
9
10
11
let                                      //声明变量(可以块级作用域)无变量提升
const // 声明常量(内存地址)声明必须赋值赋值后不能修改
symbol //新增数据类型无法被更改的数据类型(独一无二的)
let 名=symbol()
全局作用域 写在script标签最外层的
块级作用域 被{}包裹的作用域使用letconst声明可形成块级作用域
函数作用域 函数function(){}中声明变量生成作用域
尽量减少使用全局变量防止全局污染
作用域链
函数执行时会优先查找当前函数作用域中查找变量
如果当前作用域查找不到则会逐级查找父级作用域

垃圾回收机制

1
2
3
4
5
6
7
8
9
内存生命周期
js环境分配的内存是如下生命周期
1.内存分配:变量声明.函数.对象系统自动分配内存
2.内存使用:使用变量,函数等
3.内存回收:使用完毕,自动垃圾回收
全局变量一般不会回收(关闭页面回收)
局部变量值不用了会被自动回收掉
内存泄漏:分配的内存由于某些原因未释放或无法释放叫内存泄漏
标记清除法(现用)和引用计数法

闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
闭包=内层函数+外层函数的变量
作用:封闭数据,提供操作,外部也可以访问函数内部的变量(保证数据的私密性)
问题:可能会引起内存泄漏
基本格式:
function outer() {
let i =1
function fn(){
log(i)
}
return fn
}
const fun =outer()
fun()

变量提升

1
2
3
var中才有变量提升
1.把所有var声明变量提升到当前作用域最前面
2.只提升,不赋值

函数进阶

函数提升

1
2
3
1.会把所有函数声明提升到当前作用域的最前面
2. 只会提升函数声明,不提升函数调用
函数表达式必须先声明和赋值后调用

函数参数

1
2
3
4
5
1.动态参数
arguments 是函数内部内置伪数组变量它包含了调用函数时传入的所有实参
2.剩余参数
function getSum(a,b,...arr){}
使用三个...接收传进来的剩余参数形成数组(真数组)多使用剩余参数

展开运算符

1
2
3
4
5
...数组
将数组数据进行展开如数组[1,2,3] 展开后就是1,2,3
使用场景
1.计算数组最大最小值
2.合并数组

箭头函数

1
2
3
4
5
6
7
8
9
10
11
()=>{}                         //箭头函数
当只传递一个参数时可省略小括号 a=>{}
只有一行代码可以省略大括号 也可以省略return
返回一个对象字面量要加括号
const fn=>({uname:uame})
fn('zjm')
箭头函数参数
箭头函数没有arguments动态参数
有剩余参数...arr
箭头函数的this指向
箭头函数this 是上一层作用域this指向

解构赋值

数组解构

1
2
3
4
5
6
7
8
9
10
11
数组解构是将数组的单元值快速批量赋值个一系列变量的简洁语法(支持多维数组)
基本语法 const [a,b,c]=[100,60,80] 右侧数组的单元值将被赋值给左侧变量
变量的顺序对应单元值位置依次进行赋值操作
js必须前面加分号的情况有两种
1.立即执行函数必须加分号结束
2.使用数组的时候前面必须加分号
传参问题
1.变量多单元格值少多戳的变量为undefined
2.变量少,单元值多可以利用剩余参数接收不然会报错
3.防止undefined传递可以直接个变量赋值
4.按需导入,忽略某些值如 const [a,b,,d]=[1,2,3,4] d=4

对象解构

1
2
3
4
5
6
7
8
9
10
11
基本语法
赋值运算符 = 左侧的{}用于批量声明变量 const { } = obj
对象属性的值将被赋值个与属性名相同的变量
注意解构的变量名不要和外面的变量名冲突否则报错
对象中找不到与变量名一致的属性值为undefined
1.为解构属性的改名
const {uname:name,age}={uname:'zjm',age:21} 这样就可以直接使用name
2.解构数组对象
const [{uname:p,age:sum}]={uname:'pig',age:21}
3.多级对象解构
const {uname,family:{mother,...}} ={uname:'pig',family{mother:'猪妈妈'}}