什么是闭包
/*
1. 闭包
当一个嵌套的内部函数引用了嵌套的外部函数的变量时
2.
使用chrome调试查看
理解1 闭包是嵌套的内部函数
2 包含被引用变量(函数)的对象
3. 产生
函数嵌套
内部函数引用了外部函数的数据(变量/函数)
*/
function fn1() {
var a =2
var b
function fn2(){ // 执行函数定义就会产生闭包
var c=5
console.log(a);
}
fn2()
}
fn1()
闭包的一个小案例
虽然这个问题使用 let的块级作用域就可以解决 但是 使用闭包能让你知道 闭包能够延长变量的作用域 只要闭包存在 这个 变量就一直存在
<body>
<div>
<button>测试1</button>
</div>
<div>
<button>测试2</button>
</div>
<div>
<button>测试3</button>
</div>
<script>
var btns = document.getElementsByTagName('button')
// for(i =0,length=btns.length;i<length;i++) {
// btns[i].index = i
// btns[i].onclick = function () {
// console.log('第'+(this.index+1)+'个button');
// }
// }
for(i =0,length=btns.length;i<length;i++) {
(function(i){
btns[i].onclick = function () {
console.log('第'+(i+1)+'个button');
}
})(i)
}
</script>
闭包作用
// 将函数作为另一个函数的返回值
function fn1() {
var a =2
function fn2(){
a++
console.log(a);
}
return fn2
}
var f =fn1()
f() // 3
f() // 4
fn1()
// 将函数作为实参传递给另一个函数调用
function showDelay(msg,time) {
setTimeout(function () {
alert(msg)
},time)
}
showDelay("yoke",1000)
// 闭包作用
/*
使用函数内部的变量在函数执行完后,依然存活在内存中(延长了局部变量的生命周期)
让函数外部可以操作到函数内部的数据
*/
/*
闭包产生
在嵌套内部函数定义执行完成时就产生了
死亡
在嵌套的内部函数成为垃圾对象时
*/
闭包的应用
/*
具有特定功能的js文件
将所有的数据和功能都封装在一个函数内部(私有的)
只向外暴露一个包含n个方法的对象或函数
模块的使用者 只需要通过模块暴露的对象调用方法来实现对应的功能
*/
const {do1thing,dothing} = module1()
module2.dothing()
module2.do1thing()
module2.dothing()
function module1() {
var msg ='hello'
function dothing() {
console.log('dothing '+msg.toUpperCase());
}
function do1thing() {
msg += '1'
console.log("do1 "+msg);
}
return{
do1thing,
dothing
}
}
(function module() {
var msg ='hello'
function dothing() {
console.log('dothing '+msg.toUpperCase());
}
function do1thing() {
msg += '1'
console.log("do1 "+msg);
}
window.module2 ={
dothing,do1thing
}
})()
闭包缺点
/*
缺点
函数执行完后 函数内的局部变量没有释放
容易造成内存泄露
解决
少用
及时释放
*/
function f1() {
var arr = new Array(100)
function fn2() {
console.log(arr.length);
}
return fn2
}
var f = f1()
f()
f = null
内存溢出与内存泄露
1 内存溢出
一种程序运行出现的错误
当程序运行需要的内存超过了剩余的内存时
2. 内存泄露
占用的内存没有及时释放
内存泄露积累多了就容易导致内存溢出
常见的内存泄露
意外的全局变量
没有及时清理的计时器或回调函数
闭包
面试题
//代码片段一
var name = "The Window";
var object = {
name: "My Object",
getNameFunc: function () {
return function () {
return this.name;
};
}
};
// alert(object.getNameFunc()()); //? the window
//代码片段二
var name2 = "The Window";
var object2 = {
name2: "My Object",
getNameFunc: function () {
var that = this;
return function () {
return that.name2;
};
}
};
// alert(object2.getNameFunc()()); //? my object
function fun(n, o) {
console.log(o)
return {
fun: function (m) {
return fun(m, n)
}
}
}
var a = fun(0)
console.log(a);
a.fun(1)
a.fun(2)
a.fun(3) //undefined,0,0,0
var b = fun(0).fun(1).fun(2).fun(3) //undefined,0,1,2
var c = fun(0).fun(1)
console.log(c);
c.fun(2)
c.fun(3) //undefined,0,1,1