这几天也在看一些javascript的知识,算是对以往的一个复习,现小记一下,方便以后查询。
相信大家在研究javascript的高级特性的时候,肯定会遇到闭包的概念,自己在各种复习资料中,也发现了不同作者的不同理解,为了更好的理解,也综合了一下大家的见解,现总结如下:
1、什么是闭包
闭包的严格定义是“由函数(环境)及其封闭的自由变量组成的集合体。这个定义有些晦涩难懂,我们暂且不用管;
实际上,闭包不是一门技术,是一个语言特性;
通俗的讲,javascript中每个函数都是一个闭包,但通常意义上嵌套的函数更能体现闭包的特性
2、什么时候产生闭包
首先看一个例子
①内部函数读取全局变量
1 var n='fanfan'; 2 3 function f1(){ 4 5 alert(n); 6 7 } 8 9 f1(); // fanfan
②函数外部读取函数内部变量
1 function f1(){ 2 3 var n='fanfan'; 4 5 } 6 7 alert(n); // error
说明,函数外部读取不了函数内部变量,但是如果从外部读取内部变量,可用到下面方法
1 function f1(){ 2 3 var n='fanfan'; 4 5 function f2(){ 6 7 alert(n); 8 9 } 10 11 return f2; 12 13 } 14 15 var result=f1(); 16 17 result(); // fanfan
这样就做到了,在函数f1外部,读取到了内部的变量,而此时就产生了闭包。
所以,当一个函数返回他内部定义的一个函数时,就产生了一个闭包(外部函数返回了内部函数的引用)
闭包就是将函数内部和函数外部连接起来的一座桥梁。
闭包不但包括被返回的函数,还包括这个函数的定义环境。
可通过下面的例子理解
1 var generateClosure = function() { 2 var count = 0; 3 var get = function() { 4 count ++; 5 return count; 6 }; 7 return get; 8 }; 9 var counter1 = generateClosure(); 10 var counter2 = generateClosure(); 11 console.log(counter1()); // 输出 1 12 console.log(counter2()); // 输出 1 13 console.log(counter1()); // 输出 2 14 console.log(counter1()); // 输出 3 15 console.log(counter2()); // 输出 2
上面这个例子解释了闭包是如何产生的:
counter1 和 counter2 分别调用了 generateClosure() 函数,生成了两个闭包的实例,
它们内部引用的 count 变量分别属于各自的运行环境。
我们可以理解为,在 generateClosure() 返回 get 函数时,私下将 get 可能引用到的 generateClosure() 函数的内部变量(也就是 count 变量)也返回了,
并在内存中生成了一个副本,之后 generateClosure() 返回的函数的两个实例 counter1和 counter2 就是相互独立的了。
3、闭包的用途
①全局访问函数内部的属性
②面向对象编程中,模拟私有属性