JavaScript 透过代码看闭包

JavaScript 闭包问题

01 闭包的定义

当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。

02 闭包的作用

  1. 实现公有变量(eg.函数累加器)
  2. 可以做缓存(存储结构)
  3. 可以实现封装,属性私有化
  4. 模块化开发,防止污染全局变量

03 闭包解决方法

下面的代码存在闭包问题,本意是在test函数中,给arr数组的每一个元素循环赋值为一个能够打印索引的匿名函数,并用myarr变量来接收test函数的返回值arr数组,接着用循环对myarr中每个元素执行,并打印对应的索引。但最后的打印结果是10个10。

function test() {
	var arr = [];
	for (var i = 0; i < 10; i++) {
		arr[i] = function() {
			document.write(i + " ");
		}
	}
	return arr;
}

var myarr = test();
for (var j = 0; j < 10; j++) {
	myarr[j]();
}
// 输出--> 10 10 10 10 10 10 10 10 10 10

运行截图:
闭包问题
解决方法1:采用立即执行函数(推荐)

function test() {
	var arr = [];
	for (var i = 0; i < 10; i++) {
		(function(j) {
			// j = 0 1 2 3 4 5 6 7 8 9
			arr[j] = function() {
				document.write(j + " ");
			}
		}(i));
	}
	return arr;
}

var myarr = test();
for (var j = 0; j < 10; j++) {
	myarr[j]();
}

运行截图:
解决方案1,立即函数

解决方法2:用let定义变量i

function test() {
	var arr = [];
	for (let i = 0; i < 10; i++) {
		arr[i] = function() {
			document.write(i + " ");
		}
	}
	return arr;
}

var myarr = test();
for (var j = 0; j < 10; j++) {
	myarr[j]();
}

运行截图:
解决方案2,let

04 闭包例题练习

例题1:考查闭包输出

// 例题1
var a = 0,
	b = 0;

function A(a) {
	A = function(b) { 
		console.log("inside:");
		console.log(a + b++); //4
	}
	console.log("outside:");
	console.log(a++); //1
}
A(1);
A(2);

运行截图:
例题1
代码解析:在第一次调用A函数的时候, A函数被重新赋值为了function(b){console.log("inside:");console.log(a + b++);};
console.log输出a之后,a的值加1,即a=2。此时需要注意,在初始的A当中,形参a其实是一个局部变量,当重置A函数的时候,新的A函数调用了原有A函数作用域中的局部变量a,构成了闭包,a这个局部变量被保存(所以此时a=2,新的形参b=2,相加得4)。

例题2:私有化变量

// 例题2:私有化变量
function Person(name, age, sex) {
	var a = 0;
	this.name = name;
	this.age = age;
	this.sex = sex;

	function sss() {
		a++;
		document.write(a);
	}
	this.say = sss; //将sss这个函数赋给了say变量
	//相当于
	//this.say = function() {
	//	a++;
	//	document.write(a);
	//};
}
var oPerson = new Person();
oPerson.say(); //1
oPerson.say(); //2
var oPerson1 = new Person();
oPerson1.say(); //1

运行截图:
例题2
个人笔记,欢迎大家交流探讨!

猜你喜欢

转载自blog.csdn.net/Yuki_yuhan/article/details/107975297
今日推荐