js---闭包

本文详细介绍了JavaScript中的闭包概念,包括其生命周期(在内部函数定义时产生,成为垃圾对象时死亡)、应用场景(如自定义JS模块)以及闭包可能导致的内存问题和内存泄漏。同时,提供了测试题来加深理解闭包中`this`的指向问题。文章还提及了解决闭包内存占用的策略,如避免不必要的闭包使用和及时释放引用。
摘要由CSDN通过智能技术生成

闭包:函数嵌套+内部函数引用了外部函数的变量

一、闭包的声明周期

  1. 产生:在嵌套的内部函数定义执行完时就产生了(不是在调用)
  2. 死亡:在嵌套的内部函数成为垃圾对象时
function fn1() {
	// 此时闭包就已经产生了(函数提升,内部函数对象已经创建了)
	var a = 2;
	function fn2() {
		a++;
		console.log(a);
	}
	return fn2;
}
var f = fn1();
f(); //3
f(); //4
f = null; // 闭包死亡(包含闭包的函数对象成为垃圾对象)
// 3-6行执行完才会产生闭包。
1. fn1() {
2. var a = 2;
3.	var fn2 = function() {
4.		a++;
5.		console.log(a);
6.	}
7.	return fn2;
8. }
9. var f = fn1();
f(); //3
f(); //4
f = null; // 闭包死亡(包含闭包的函数对象成为垃圾对象)

二、闭包的应用——自定义js模块

定义js模块:

  • 具有特定功能的js文件
  • 将所有数据和功能都封装在一个函数内部(私有的)
  • 只向外暴露一个包含n个方法的对象或函数
  • 模块的使用者,只需要通过模块暴露的对象调用方法来实现对应的功能

(一)

function myModule() {
	// 私有数据
	var msg = 'hahaha';
	// 操作数据的函数
	function doSomething() {
		console.log('doSomething' + msg.toUpperCase());
	}
	function doOtherthing() {
		console.log('doOtherthing' + msg.toLowerCase());
	}
	// 向外暴露对象(给外补使用的方法)
	return {
		doSomething: doSomething,
		doOtherthing: doOtherting
	}
}
var module = myModule();
module.doSomething();
module.doOtherthing();

(二)

(function() {
	// 私有数据
	var msg = 'hahaha';
	// 操作数据的函数
	function doSomething() {
		console.log('doSomething' + msg.toUpperCase());
	}
	function doOtherthing() {
		console.log('doOtherthing' + msg.toLowerCase());
	}
	window.myModule2 = {
		doSomething: doSomething,
		doOtherthing: doOtherting
	}
})()
myModule2 .doSomething();
myModule2.doOtherting();

三、闭包的缺点及解决

  1. 缺点:
  • 函数执行完后,函数内的局部变量没有释放,占用内存时间会变长
  • 容易造成内存泄漏
  1. 解决:
  • 能不用闭包就不用
  • 及时释放
function fn1() {
	var arr = new Array(1000000);
	function fn2() {
		console.log('111');
	}
	return fn2;
}
var f = fn1();
f();
f = null; // 让内部函数成为垃圾对象=>回收闭包

内存溢出与内存泄漏

  1. 内存溢出
  • 一种程序运行出现的错误
  • 当程序运行需要的内存超过了剩余的内存时,就会抛出内存溢出的错误
  1. 内存泄漏
  • 占用的内存没有及时释放
  • 内存泄漏积累多了就容易导致内存溢出
  • 常见的内存泄漏
    (1)意外的全局变量
    (2)没有及时清理的计时器或回调函数
    (3)闭包
// 1. 内存溢出
var obj = {};
for (var i = 0; i<10000; i++) {
	obj[i] = new Array(10000000);
	console.log('111');
}

// 2. 内存泄漏
// 意外的全局变量
function fn() {
	a = 1;
	console.log(a);
}
fn();
// 启动循环定时器不清理
var interval = setInterval(function() {
	console.log('111');
}, 1000)
// clearInterval(interval);

// 闭包
function fn1() {
	var arr = new Array(1000000);
	function fn2() {
		console.log('111');
	}
	return fn2;
}
var f = fn1();
f();
// f = null; 

四、测试题

测试题1:
var name = 'aaa';
var object = {
	name: 'bbb';
	getNameFunc() {
		return function() {
			return this.name;
		};
	}
};
console.log(object.getNameFunc()()); // aaa
var name = 'aaa';
var object = {
	name: 'bbb';
	getNameFunc() {
		var that = this;
		return function() {
			return that.name;
		};
	}
};
console.log(object.getNameFunc()()); // bbb
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值