对闭包的理解

从网上看了一些关于js闭包的文章,现在总算是明白之前遇到过的一系列问题,比如:

function a() {
	var nodes = [1,2,3,4,5];
	var arr = [];
	for(var i=0; i<nodes.length; i++) {
		return function() {
			arr[i] = i;
		}
	}
	return arr;
}
var b = a();
alert(b);

比如这段看似没什么语法问题的代码,为啥返回结果会让人如此的蛋疼呢?我想如果不理解或不知道闭包的话,这个问题还真回答不了,其中闭包涉及到了关于执行环境、作用域链等js中比较难理解且又很重要的概念,关于这些概念,我相信baidu或google会有很多文章说明,我技术有限,基本上没能力解释清楚。在此只想show一下我在看这些文章时候对例子的一点想法,仅供参考^_^!

//理解闭包
function a() {
	var n = 2;//私有变量,只有作用域链包含变量n的函数(方法)有权访问n
	function b() {
		alert(n);
	}
	return b;
	
	//var b = function() {//功能同上
		//alert(n);
	//}();
}
var c = a();//c()是一个外部方法,如果没有闭包,它无法访问a()的私有变量
c();//此时c()函数“可以访问”(间接访问)a的私有变量,
//在a()执行完后,其私有变量n(包括a和b对象)并没有被销毁(暂时保存在内存中),
//因为c()的执行依赖b(),b()的执行依赖变量n,且b()有权访问变量n,这就形成了所谓的闭包



//闭包的特性
function print(str) {
	document.write(str + ' ');
}

var outer = [];


function clouseTest() {
	for(var i=0; i<5; i++){
		var obj ={};
		obj.func = function() {//实际上,这个函数并未执行
			print(i);//在这里,i可以是任何值或变量
			print('任何值');
		};
		outer.push(obj);
	}
};
clouseTest();//此时i的值是5

outer[0].func();//5,任何值
outer[1].func();//5,任何值
outer[2].func();//5,任何值
outer[3].func();//5,任何值
outer[4].func();//5,任何值
alert(toString(outer[0].func()));

function clouseTest2() {
	for(var i=0; i<5; i++){
		var obj ={};
		obj.func = function(no) {//申明一个匿名函数并立即执行它
			return function() {
				print(no);//可以访问i变量
			}
		}(i);//闭包函数被执行并返回了值,这样,外部函数就可以间接访问函数内部的变量了
		outer.push(obj);
	}
	//i的值是5
};
clouseTest2();

outer[0].func();//0
outer[1].func();//1
outer[2].func();//2
outer[3].func();//3
outer[4].func();//4


function clouseTest3() {
	for(var i=0; i<5; i++){
		var obj ={};
		obj.func = function() {//此时func变成了obj对象的一个属性而已
			print(i);
		}();
		outer.push(obj);
	}
};
clouseTest3();//此时i的值是5

outer[0].func;//0,此时func变成了obj对象的一个属性而已
outer[1].func;//1
outer[2].func;//2
outer[3].func;//3
outer[4].func;//4


/*
 * 例子来自《JavaScript高级程序设计》(第2版)
*/
function createFunctions(){
	var result = new Array();
	for (var i = 0; i < 3; i++) {
		result[i] = function(){
			return i;
		};
	}
	return result;
}

var funcs = createFunctions();//因createFunctions()返回数组(result),funcs直接指向了result[i]()

for (var i = 0; i < funcs.length; i++) {
	//document.write(funcs[i]()+'');
	alert(funcs[i]);//返回3个function(){return i;}函数本身,其中i的值是3
}

//闭包应该注意的问题

 * 1、由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成
 *    网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
 * 2、闭包会在外部函数改变内部函数的变量值。所以,如果你把外部函数当作对象(object)使用,把闭包
 *    当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,
 *    不要随便改变外部函数内部变量的值。
 

//理解闭包了???
var name = 'window';
var test1 = {
	name : 'me',
	getName : function() {
		return function() {
			return this.name;
		}
	}
};
alert(test1.getName()());//输出'window'

var test2 = {
	name : 'me',
	getName : function() {//特权方法,参阅“javascript私有成员”一文
		var that = this;
		return function() {
			return that.name;
		}
	}
};
alert(test2.getName()());//输出'me'

还剩下一个问题就是闭包有什么用?这个我觉得还是自己去实践中摸索归纳比较好,这里推荐一篇觉得说的比较好的文章:

JavaScript内核系列 第7章 闭包

posted @ 2011-03-04 17:38  chemdemo  阅读(313)  评论(0编辑  收藏  举报