JS进阶
作用域
作用域规定了变量能够访问的范围,离开了这个范围变量便不能被访问
作用域分为了两种:局部作用域,全局作用域
局部作用域
局部作用域分为:函数作用域,块作用域
函数作用域
在函数内部的变量只能在函数内部被访问,外部无法直接访问
- 函数内部声明的变量,在函数外部无法被访问
- 函数的参数就是函数的局部变量
- 不同的函数声明的局部变量无法互相被访问
- 函数执行完毕后,变量就被清除了
块作用域
- let声明的变量有块作用域,var声明的变量没有块作用域
- const声明的常量也会产生块作用域
- 不同的代码块的变量无法互相访问
全局作用域
全局作用域中的变量可以被其他任意作用域中访问
作用域链
作用域链的本质是底层的变量查找机制
在变量被执行的时候,会优先在当前作用于下面查找
如果当前作用域下面找不到该变量,就逐级在父作用域下面依次查找
- 嵌套关系的作用域串联起来形成了作用域链
- 相同的作用域链中按着从小到大的规则查找
- 子作用域能够访问父作用域,父作用域访问不了子作用域
垃圾回收机制
JS环境下分配的内存,一般都有生命周期
- 内存分配:当我们声明变量,函数,对象的时候,系统会自动为他们分配内存
- 内存使用:即读写内存,也就是使用变量。函数等
- 内存回收:使用完毕,由垃圾回收器自动回收不再使用的内存
全局变量一般不会被回收,直到关闭页面
一般情况下局部变量的值在不使用了之后就会被自动回收
内存泄漏:程序中分配的内存由于某种原因程序未释放或无法释放叫做内存泄漏
栈堆的内存分配
- 栈:由操作系统自动分配释放函数的参数值,局部变量等,基本数据类型放在栈中
- 堆:一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收,复杂数据类型放到堆里面
如果两个对象相互引用,尽管他们不再使用,垃圾回收器不会进行回收,导致内存泄漏
闭包
一个函数对周围状态的引用捆绑在一起,内层函数中访问到外层函数的作用域
闭包 = 内层函数+外层函数的变量
外部的函数可以访问内部函数的变量
闭包的应用:数据的私有
变量提升
只有var声明的变量有变量提升现象
在代码执行之前,会把所有在当前作用域下声明的var变量,提升到当前作用域下的最前面
只提升声明不提升赋值
函数提升
会把所有函数声明提升到当前作用域的最前面,只提升函数声明,不提升函数调用
函数表达式不会提升
函数动态参数
arguments在每个函数中都存在
arguments是动态参数,只存在于函数里面
arguments是一个伪数组
函数的剩余参数
剩余参数允许将一个不定数量的参数表示为一个数组
剩余参数放在传入的所有参数的最后面,用于获取多余的参数,是一个真数组
function(...arr){
console.log(arr)
}
箭头函数
引入箭头函数的目的是更简短的函数写法并且不绑定this,箭头函数的语法比函数表达式更简洁
箭头函数用于替代匿名函数更实用
const fn = ()=>{
}
箭头函数可以直接返回一个对象
const fn = (uname)=>({name:uname})
箭头函数中没有arguments只有剩余参数
箭头函数中的this
箭头函数中不会自己创建this,会沿着作用域链沿用上一级的this
解构赋值
数组解构
数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法
=左侧的[]用于批量声明变量,右侧数组的单元值将被赋值给左侧的变量
const [max,min,avg] = [100,80,60]
在交换两个变量的时候需要加分号
两个立即执行函数之间必须加分号
let a= 1
let b = 2;
[b,a] = [a,b]
console.log(a,b)
对象解构
对象解构是将对象属性和方法快速批量赋值给一系列变量的简洁语法
对象属性的值将赋值与属性名相同的变量
对象解构的变量名可以重新改名
旧名字:新名字
const{uname:username,age} = {'xxx',18}
解构数组对象
const phone = [{
goodsName:'小米'
price:9999
}]
const [{goodsName:name,price}] = phone
多级对象解构
对象可能有很多,需要标明是在哪一个对象解构的
const pig = {
name:'佩奇',
family:{
mother:'猪妈妈'
father:'猪爸爸'
sister:'乔治'
},
age:6
}
const{name,family:{mother,father,sister},age} == pig;
forEach循环
forEach()方法用于调用数组的各个元素,并将元素传递给回调函数
参数中item是必写的,index可写可不写
适合于遍历数组对象
forEach(function(当前数组元素,当前元素索引号){
})
const arr = ['a','b','c']
arr.forEach(function(item,index){
console.log(item)//a,b,c
console.log(index)//1,2,3
})