js闭包详解

news/2024/7/19 13:54:51 标签: js, 作用链, 闭包, 循环变量显示

以前只听说过闭包(closure),并没有深入研究过,今天来仔细看一看闭包究竟是个什么东西。

1.认识闭包

闭包是一个有权访问另一个函数作用域中的变量的函数。通常创建的方法是在一个函数内创建另一个函数,是该函数可以访问其局部变量。

优点:可以使函数的局部变量被保存在内存中,不被js垃圾回收器销毁。避免全局变量被污染。正常情况下,局部变量在函数执行完成后会被销毁,而闭包可以使该变量不被销毁。

缺点闭包会常住内存,对内存消耗大,容易造成内存溢出,在IE上更易崩溃。可在使用完后使对象等于null来清空对象。


2.了解作用链

作用链js中所有的变量都是对象的一个属性,而该对象可能也是另一个对象的属性,但所有对象都是window对象的属性,那么他们之间的关系就形成了一个链式,即是作用链

作用域:js变量的生命活动范围,超出该范围将会被GC销毁。

注意:在js中没有用var声明的变量是全局变量,且是window对象的属性,有var声明的变量才是局部变量,归函数所有。


3.闭包的特性

  a.闭包是一个嵌套在函数中的函数。

  b.函数内部可以引用外部函数的参数和变量。

  c.闭包的参数和变量不会被垃圾回收机制回收。

(垃圾回收机制:回收不被引用的对象;回收2个互相引用而不被第3者引用的对象)


4.实例分析

<script type="text/javascript">
	var a = [];
	function testa(){
		var i= 0;
		for (;i<3;i=i+1){
			a[i]=function(){
				alert(i);
			};
		}
	}
	testa();
	a[0]();//3
	a[1]();//3
	a[2]();//3
</script>

上诉代码对数组a使用了闭包结构,i变量确实被存储了,但是却全部变成了3,这是因为闭包中所存储的变量并不是变量的值,而是闭包的一个引用,当testa方法执行完成后,i变量已经成为了3,之后在引用i时,只会是3.那么如何存储所有变量呢,我们可以让内部函数在循环创建的时候立即执行,并且捕捉当前的索引值,然后记录在自己的一个本地变量里.然后利用返回函数的方法,重写内部函数,让下一次调用的时候,返回本地变量的值,例如:

<script type="text/javascript">
	var a = [];
	function testa(){
		var i= 0;
		for (;i<3;i=i+1){
			a[i]=(function(i){//立即执行当前方法
				return function(){//重写返回方法
					alert(i);
				};
			})(i);//记录i的当前值
		}
	}
	testa();
	a[0]();//0
	a[1]();//1
	a[2]();//2
</script>
这里的return是一个闭包函数。



http://www.niftyadmin.cn/n/725653.html

相关文章

好文摘抄

http://blog.donews.com/shuabang/ 刷榜那些事儿&#xff1a;顺流逆流 文&#xff1a; AppStore刷榜那些事儿 部分摘录&#xff1a; “知易行难&#xff0c;人之患在于好为人师&#xff0c;差不多得了&#xff0c;不要把没头脑的经验当**一样到处撒。另外奉劝那些喜欢听导师讲…

javascript callee()属性

要想了解callee属性&#xff0c;我们先得了解javascript中的arguments对象&#xff0c;在《javascript高级程序设计》的第三章中&#xff0c;讲到了arguments对象&#xff0c;arguments对象有以下属性&#xff1a; 定义 属性名定义length属性返回实际传入的参数个数。callee属…

iframe的使用

1、iframe 定义和用法 iframe 元素会创建包含另外一个文档的内联框架&#xff08;即行内框架&#xff09;。 HTML 与 XHTML 之间的差异 在 HTML 4.1 Strict DTD 和 XHTML 1.0 Strict DTD 中&#xff0c;不支持 iframe 元素。 提示&#xff1a;a.您可以把需要的文本…

nullnullPHP之session入库

在本篇文章中,我们主要介绍nullnull的内容,自我感觉有个不错的建议和大家分享下 义思名顾&#xff0c;就是重写session制机&#xff0c;在session的周期内&#xff0c;获得到session的数据并记录到数据库&#xff0c;和获得的进程。 每日一道理 流逝的日子像一片片凋零的枯叶与…

javascript apply()与call()方法

对于apply()与call()方法&#xff0c;先看其定义&#xff1a; apply() 语法&#xff1a; functionObject.apply([thisObject,[,argArray]]); 参数描述thisObject可选/Object类型指定执行functionObject函数时&#xff0c;函数内部this指针引用的对象。argsArray可选/Array a…

C#如何获取object对象的属性值

/// <summary> /// 获取一个类指定的属性值 /// </summary> /// <param name"info">object对象</param> /// <param name"field">属性名称</param> /// <returns></returns> …

div包裹的iframe有5px的高度差问题

最近遇到一个问题&#xff1a;用一个div包裹一个iframe&#xff0c;但无论如何&#xff0c;div的高度都比iframe高了5px。百思不得其解&#xff0c;后来在网上多方查找&#xff0c;才发现问题的根源所在。 问题&#xff1a;div高度大于iframe高度5px左右。 <div id"if…

javascript中的Object.defineProperty()与getOwnPropertyNames ()方法

在接触javascript面向对象的高级部分时&#xff0c;我一下子傻缺了。我看的是《javascript高级程序设计》第三版&#xff0c;其中第六章讲到面向对象的程序设计。我想接触过java&#xff0c;php5等语言的小伙伴们&#xff0c;对面向对象那是再熟悉不过了。我也一样&#xff0c;…