闭包
定义:闭包是指在JavaScript中一个函数能够访问并操作其外部作用域的变量的能力。
原理:一个内部函数能够访问和操作外部函数作用域中的变量,即使外部函数已经执行完毕(外部作用域理应被销毁),但因为内部函数仍然存在,并保持着对外部函数作用域的引用,所以这些变量得以保留,这就形成了闭包。
闭包解决了什么?
1.可以读取函数内部的变量。
2.让这些变量的值始终存储在内存中
闭包就是将函数内部和函数外部连接起来的一座桥梁,闭包随处可将,例如一个Ajax
请求成功的回调,一个事件绑定的回调方法,一个settimeout
的延时回调。无论使用何种方式对函数类型值进行传递,当函数在别处被调用时,都有闭包的身影。
使用闭包应该注意什么?
- 闭包会增加内存开销,因为闭包会保留其外部函数的作用域链,导致这些变量不能被垃圾回收机制回收。解决办法,在退出函数之前,将不使用的局部变量删除。
- 内存泄漏,不再用到的内存,没有及时释放。
- 代码难以维护,闭包内部是可以访问上级作用域,而如果闭包又是异步执行的话,一定要清楚上级作用域都发生了什么,而这样就需要对代码的运行逻辑和
JS
运行机制相当了解才能弄明白究竟发生了什么。 - 闭包可能会导致一些难以察觉的错误,因为它允许内部函数访问并修改外部函数的变量。
闭包的this指向?
this指向的一般规则
- 函数在普通调用时,this指向全局对象,严格模式下指向undefined
- 函数作为对象方法调用时,this指向调用该函数的对象
- 函数作为构造函数时,this指向新创建的对象实例
- 使用call,bind,apply方法时,可以显式的绑定到指定的对象。
闭包本身不会改变this的指向规则。闭包中this指向取决于闭包是如何被调用的,而不是闭包被如何定义的。
指向window全局对象。
内存泄漏
定义:无法正确释放不再使用的内存,导致内存占用持续增长,最终有可能导致性能下降或者程序崩溃。
原因:1.未清除的定时器或回调(事件监听器addEventListener
)2.闭包中的循环引用。3.全局对象。4.DOM
引用未清理。(从DOM
中删除元素,如果js
有对这个元素的引用,元素将不会被垃圾回收器回收)
解决措施:1.定期清理。2.避免不必要的全局变量。3.管理DOM
引用。(从DOM
中删除元素,同时删除JavaScript中的引用)
垃圾回收机制
定义:自动化内存管理技术,负责在程序运行过程中检测并回收不再使用的内存,释放资源并避免内存泄漏
原理:自动扫描内存中的对象,标记那些仍然被使用的对象,将未使用的对象标记为垃圾,释放这些垃圾对象的内存空间。这个过程依赖来两种主要的垃圾回收算法
- 标记-清除算法。垃圾回收器从根对象开始,递归标记所有可达的对象为活动对象。遍历堆内存,回收未被标记为活动对象的内存空间。
- 引用计数算法。每个对象有一个引用计数器,记录当前有多少个引用指向该对象,该对象被引用,引用计数器+1,引用被释放,引用计数器-1,引用计数器为0,该对象不再被引用,可以被回收。
优化:为了提高垃圾回收机制的效率,现代JavaScript引擎(V8)引入了复杂的垃圾回收机制
- 增量回收。将垃圾回收工作分为多个小步骤,避免长时间卡顿。
- 分代回收。将内存分为两代,新生代和老生代。长期存活的对象放置在老生代,垃圾回收机制频繁清理新生代中的对象。提高了垃圾回收机制的效率。
let const var
let,const声明的变量是块级变量,不存在变量提升。let声明的变量允许重新赋值,const不允许。
var声明的变量是全局变量,存在变量提升
作用域
- 全局作用域
- 定义:变量或者函数在整个程序中都可以被访问。 实现措施:1.函数外部使用var、let或const声明的变量将具有全局作用域。2.函数内部或函数外部不用关键字,直接赋值变量(不推荐)。 特点:全局可访问,全局作用域容易被污染 如何避免全局作用域被污染?1.使用立即执行函数。2.使用模块,
ES6
模块。3.谨慎使用全局变量。
- 定义:变量或者函数在整个程序中都可以被访问。 实现措施:1.函数外部使用var、let或const声明的变量将具有全局作用域。2.函数内部或函数外部不用关键字,直接赋值变量(不推荐)。 特点:全局可访问,全局作用域容易被污染 如何避免全局作用域被污染?1.使用立即执行函数。2.使用模块,
- 块级作用域
- 定义:变量或者函数在一个代码块中有效,在代码块外无效。代码块如
if
语句,for
语句。通过let
,const
关键字实现,在ES6
之前,只有函数作用域。 作用:避免变量提升和闭包。
- 定义:变量或者函数在一个代码块中有效,在代码块外无效。代码块如
- 函数作用域
- 定义:定义在函数内部的变量和函数只能在函数内被访问,函数外部无法访问。函数作用域通过函数作用域链实现的。