什么是闭包?
- 闭包就是 能够读取其他函数内部变量的函数
- 闭包是指有权访问另一个函数作用域中变量的函数
- 创建闭包最常见的方式就是在一个函数内部创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用域链
- 闭包的特性:
- 函数内再嵌套函数
- 内部函数可以引用外层的参数和变量
- 参数和变量不会被
垃圾回收机制
回收
说说你对闭包的理解
- 使用闭包主要是为了设计私有的变量和方法
- 闭包的优点是可以避免全局变量的污染,
- 缺点是闭包会常驻内存,会增大内存使用量,使用不当,很容易造成泄漏
- 在js中,函数即闭包,只有函数才会产生作用域的概念
- 闭包的另一个用处,是封装对象的私有属性和私有方法
- 好处:能够实现封装和缓存
- 坏处:消耗内存、不正当使用造成内存溢出的问题
使用闭包的注意点
- 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄漏
- 解决方案是:在退出函数之前,将不使用的局部变量全部删除。
闭包的应用场景
1.setTimeout
原生的setTimeout传递的第一个函数不能带参数,通过闭包可以实现传参效果。
function f1(a){
function f2(){
console.log(a)
}
return f2
}
var fun = f1(1)
// 只是赋了一个函数调用给fun,调用f1(1)的时候,返回的是f2里面的打印
setTimeout(fun,1000) //1秒之后打印出1
2.回调
定义行为,然后把它关联到某个用户事件上(点击或按键)。代码通常会作为一个回调(事件触发时调用的函数)绑定到事件上。
<body>
<div class="box"></div>
<ul>
<li>a1</li>
<li>a2</li>
<li>a3</li>
<li>a4</li>
</ul>
</body>
<script>
var lis = document.querySelectorAll('ul li')
//将每个 i 的值赋给了 n
for (var i = 0, len = lis.length; i < len; i++){
(function (n){
lis[n].onclick = function (){
console.log(n)//4
}
})(i)
}
</script>
3.防抖和节流
什么是防抖和节流??
闭包相关知识
1.作用域
一个名字起作用的范围
var a = 123 // 全局作用域
function fn(){
var b = 456 // 局部作用域
}
fn()
console.log(a)//123
console.log(b)//报错
function fn(){
var b = 4 //局部变量
b++
console.log(b)
}
fn()//5
fn()//5
fn()//5
var b = 4 // 全局变量
function fn(){
b++
console.log(b)
}
fn()//5
fn()//6
fn()//7
2.一个例子
- 闭包:直接在内部调用了内部函数,无论调用多少次outer,都是inner的调用
function outer(){
var a = 1
function inner(){
a++
console.log(a)
}
inner()
}
outer()//2
outer()//2
outer()//2
// 在外部访问或操作局部变量
// inner() // 报错
// console.log(a) // 报错
- 闭包:返回了内部函数,并在外部调用.
- 在外部操作某个局部变量
function outer(){
var a = 1
function inner(){
a++
console.log(a)
}
return inner
}
var result = outer()
result()//2
result()//3
result()//4
3.词法作用域
静态作用域 :关注点是 函数在何处定义
var a = 123
function fn1(){
console.log(a)
}
function fn2(){
var a = 456
fn1()
}
fn2()// 123
// 调用fn2的时候执行了 fn1的调用,fn1是在全局定义的。
4.动态作用域
类似 this:关注点是 函数在何处调用
function show(){
console.log(this)
}
setTimeout(show,1000) //这个是window吧
box.onclick = show //这个this是事件源
5.作用域链
本质上是一个指针列表[变量对象的引用地址,变量对象的引用地址]
- 变量对象 -> 执行上下文的一部分
- 执行上下文 -> 执行环境
- 全局执行环境 - 变量对象 -> window
- 局部执行环境 - 活动对象 也是 变量对象
6.垃圾回收机制
各大浏览器采用的垃圾回收有两种方法
- 标记清除
当变量进入执行环境时,将这个变量标记为‘进入环境’
当变量离开执行环境时,将这个变量标记为‘离开环境’,则销毁回收内存。 - 引用计数
跟踪记录每个值被引用的次数,当次数变成0时,则销毁回收内存。