javascript函数闭包

1. 事件闭包的理解

闭包是指有权限访问另一个函数作用域中的变量的函数。 在 javascript 语言中,闭包就是函数和该函数作用域的组合。从这 个概念上来讲,在 js 中,所有函数都是闭包(函数都是对象并且函 数都有和他们相关联的作用域链 scope chain)。

 官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的 环境的表达式(通常是一个函数),因而这些变量也是该表达式的一 部分。其实这 句话通俗的来说就是:JavaScript 中所有的 function 都是一个闭包。 不过一般来说,嵌套的 function 所产生的闭包更为强大,也是大部 分时候我们所谓的“闭包”。

2. 变量的作用域 要理解闭包,首先必须理解 Javascript 特殊的变量作用域。 变量的作用域无非就是两种:全局变量和局部变量。 Javascript 语言的特殊之处,就在于函数内部可以直接读取全局 变量。

案例:


<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			
//			闭包: 在js中任何一个函数都是一个闭包,但是嵌套的函数闭包作用会更大;
//			闭包: 一个函数中的变量 可以被其他函数所访问			
			//问题: 如何从外部读取函数内部的变量?
			//解决: 在 函数体内嵌套函数
//			function snake(){ 	  //创建一个蛇对象			
//				var color='white';  //创建属性
//				//var length=30;
//				var width=20;
//				var height=20;
//				function snake1(){
////					var color_01='red';
//					alert(color);
//				}
//				snake1();
//			}
//			snake();  //输出color的结果为: white
			//以上函数嵌套  是 JS中特殊的作用域立链  scope  chain
			//父对象的所有变量,对子对象都是可见的,反之则不成立
			
			function snake(){ 	  //创建一个蛇对象			
				var color='white';  //创建属性
				var width=20;
				var height=20;
				function snake1(){
					return color;
				}
//				var color_01=snake1();  return color_01;
				return snake1();
			}
			alert(snake());
		</script>
	</head>
	<body>
	</body>
</html>

练习案例1:


<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			
//			创建一个学生 对象,具备属性     color, height,weight
			function Student(){
				var color='yellow';
				var height=1.82;
				var weight=60; //表示体重的属性
				
				//第一种方法 不常用(不强大);
				//return '肤色:'+color+'身高:'+height+'体重:'+weight;
				//第二种方式: 通过在函数体内定义函数 返回,功能更加强大
				function Student_01(){
					return '肤色:'+color+'身高:'+height+'体中:'+weight;
				}
				return Student_01();
			}
//			对于以上案例: Student_01() 就是一个闭包函数

			/*闭包可以使用在许多地方.它的最大作用有两处:
				一个是前面提到的可以读取函数内部的变量,
				另一个就是让这些变量的值始终保持在内存中*/
			
		</script>
	</head>
	<body>
	</body>
</html>

案例2:

function outerFun(){
    var a=0;
  function innerFun(){
    a++;
   alert(a);
  }
}
innerFun()
上面的代码是错误的.innerFun()的作用域在 outerFun()内部,所在 outerFun()外部调用它是错误的. 改成如下,也就是闭包:
function outerFun(){
  var a=0;
  function innerFun(){
  a++;
  alert(a);
   }
  return innerFun; //注意这里
}
var obj=outerFun();

obj(); //结果为 1
obj(); //结果为 2
var obj2=outerFun();
obj2(); //结果为 1
obj2(); //结果为 2

案例3:

<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title></title>
		<script type="text/javascript">
			function outerFun() {
				var a = 0;
				alert(a);
			}
			var a = 4;
			outerFun();
			alert(a);
			//结果是 0, 4.因为在函数内部使用了
			//var 关键字 维护 a 的作用域在 outFun() 内部.
				function outerFun() {
					//没有 var
					a = 0;
					alert(a);
				}
			var a = 4;
			outerFun();
			alert(a);
			//结果为 0, 0 
				//作用域链是描述一种路径的术语, 沿着该路径可以确定变量的值.当执行 a = 0 时,
				//因为没有使用var关键字, 因此赋值操作会沿着作用域链到var a = 4;并改变其值.
		</script>
	</head>

	<body>
	</body>

</html>

案例4:

这段代码有两个特点: 1、函数 b 嵌套在函数 a 内部; 2、函数 a 返回函数 b。

这样在执行完 var c=a()后,变量 c 实际上是指向了函数 b,再执 行 c()后就会弹出一个窗口显示 i 的值(第一次为 1)。这段代码其实 就创建了一个闭包,为什么?因为函数 a 外的变量 c 引用了函数 a 内 的函数 b,

就是说: 当函数 a 的内部函数 b 被函数 a 外的一个变量引用的时候,就创建 了一个闭包。

猜你喜欢

转载自blog.csdn.net/qq_43551373/article/details/84977487