1.聊一聊闭包和垃圾回收机制
目录
2.箭头函数的特点
3.new的过程?
(1)闭包:内层函数用外层函数的局部变量就是闭包
function outer() {
let a = '变量1'
let inner = function () {
console.info(a)
}
return inner // inner 就是一个闭包函数,因为他能够访问到outer函数的作用域
}
let inner = outer() // 获得inner闭包函数
inner() //"变量1"
作用:封闭数据,提供操作,外部也可以访问函数内部的变量,实现数据的私有
<1>优点:
可以隔离作用域,不造成全局污染
- 访问其他函数内部变量
- 变量长期驻扎在内存中,不会被内存回收机制回收,即延长变量的生命周期;
- 避免定义全局变量所造成的污染
<2>缺点:
由于闭包长期驻留内存,则长期这样会导致内存泄露
闭包内存泄露的原因:
《JavaScript高级编程》书中建议:由于闭包会将它的外部函数的作用域也保存在内存中
,因此会比其他函数更占用内存,这样的话,如果过度使用闭包,就会有内存泄露的威胁。
<3> 如何解决内存泄露:
将暴露全外部的闭包变量置为null
这段代码会导致内存泄露
window.onload = function(){
let el = document.getElementById("id");
el.onclick = function(){
alert(el.id);
}
}
解决方法为
window.onload = function(){
let el = document.getElementById("id");
let id = el.id; //解除循环引用
el.onclick = function(){
alert(id);
}
el = null; // 将闭包引用的外部函数中活动对象清除
}
<4> 适用场景:
封装组件,for循环和定时器结合使用,for循环和dom事件结合.可以在性能优化的过程中,节流防抖函数的使用,导航栏获取下标的使用
(2) 什么是垃圾回收机制?
1.概述
js的垃圾回收机制是为了防止内存泄漏(已经不需要的某一块内存还一直存在着),垃圾回收机制就是不停歇的寻找这些不再使用的变量,并且释放掉它所指向的内存。
在JS中,JS的执行环境会负责管理代码执行过程中使用的内存。
2.变量的生命周期
当一个变量的生命周期结束之后,它所指向的内存就会被释放。js有两种变量,局部变量和全局变量,局部变量是在他当前的函数中产生作用,当该函数结束之后,该变量内存会被释放,全局变量的话会一直存在,直到浏览器关闭为止。
3.js垃圾回收方式
有两种方式: 标记清除、引用计数
标记清除:大部分浏览器使用这种垃圾回收,当变量进入执行环境(声明变量)的时候,垃圾回收器将该变量进行了标记,当该变量离开环境的时候,将其再度标记,随之进行删除。
引用计数:这种方式常常会引起内存的泄露,主要存在于低版本的浏览器。它的机制就是跟踪某一个值得引用次数,当声明一个变量并且将一个引用类型赋值给变量得时候引用次数加1,当这个变量指向其他一个时引用次数减1,当为0时出发回收机制进行回收。
(3) 箭头函数有哪些特点?
//普通函数
const fn=function(x) =>{
return x+x
}
console.log(fn(1)) //2
//箭头函数
const fn =x =>{
return x+x
}
console.log(fn(1)) //2
特点:
1.只有一个参数可以省略小括号
2.如果函数体只有一行代码,可以写到一行上,并且无需写 return 直接返回值 但是,如果省略了大
括号,返回默认值
3..箭头函数不绑定arguments,取而代之用rest参数…解决
4.箭头函数里面不会存在有this,会使用上级this
5.箭头函数不能作为构造函数使用
(4)new的过程?
-
一般我们在创建构造函数时,会使用new关键字的new出来一个新的对象。
-
第一步:在new开始时,先创建一个空对象,把这个空对象的隐式原型proto属性赋值给构造函数的显示原型prototype属性。
-
第二步:调用 构造函数,然后改变this 指向我们创建出来的新的空对象,给这个对象添加属性。
-
第三步:最后返回这个空对象。
-
注意:在第三步时,可以先判断我们的构造函数是否返回对象数据类型,在有返回值时,返回构造函数的返回值,在没有返回值时,返回我们创建的空对象。