此系列体验视频教程
点击观看:哔哩哔哩
闭包
闭包的生命周期
- 在内部函数定义(不是调用)完成就产生了
- 将闭包的引用设置为null,彻底清除对闭包的引用,闭包才销毁
/*
内部函数定义(不是调用)完成,闭包产生。也就意味着要调用外部函数。
*/
function record() {
console.dir(inner)
// 如果是函数表达式定义函数,在此就会产生闭包
var step = 0
/* var inner = function () { // 函数表达式定义的函数必须要到这行,函数的赋值完成,才会产生闭包
return ++step
}
console.dir(inner) */
function inner() {
return ++step // 延长了函数内部局部变量的生命周期
}
return inner
}
var r = record()
console.log(r());
console.log(r());
console.log(r());
console.dir(r)
r = null // 手动将r设置为null,也就是将内部函数的引用关系清除掉,闭包也就被销毁了。
console.dir(r)
闭包的两个作用
- 延长了局部变量的生命周期,使局部变量在函数执行之后,仍然存在于内存中
- 在函数外部可以操作函数内部的数据
闭包的缺点
内存溢出
// 内存不够、网页崩溃,所剩余的内存不够使用,浏览器就会抛出内存溢出的错误提示
var obj = {}
for (var i = 0; i < 10; i++) {
obj[i] = Array(10)
}
console.log(obj);
内存泄漏
function fn() {
var arr = Array(10) // 内存泄漏 内存占用
return function () {
return arr.length
}
}
// 内存泄漏过多就会引起内存溢出
var f = fn()
console.log(f());
f = null
练习
// 1、
var name ='xiaohua'
var obj = {
name: 'xiaoming',
getName: function () {
return function () {
console.log(name); // 使用的是全局变量,不会产生闭包
}
}
}
obj.getName()() // xiaohua
// 2、
var name ='xiaohua'
var obj = {
name: 'xiaoming',
getName: function () {
var name = 'xiaoxiao'
return function () { // 有闭包
console.log(name);
}
}
}
obj.getName()() // xiaoxiao
// 3、
var name = 'xiaohua'
var obj = {
name: 'xiaoming',
getName: function () {
var name = 'xiaoxiao'
return {
fn: function() {
console.log(name); // xiaoxiao 存在闭包的
console.log(obj.name); // xiaoming
console.log(window.name); // xiaohua
}
}
}
}
obj.getName().fn()
// 4、
var name = 'xiaohua'
function fn() {
var name = 'xiaoxiao'
return {
name: 'xiaoming',
fn2: function () {
console.log(name); // xiaoxiao 存在闭包
}
}
}
fn().fn2()