javascript 闭包、匿名函数、作用域链

1:闭包

闭包的定义 :是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。

 

 

/**
 *闭包 :是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。
 * 
 * 这两行代码访问了外部函数中的变量propertyName.即使这个内部函数被返回了,而且是在其他地方被调用了,
 * 但它仍然可以访问变量propertyName.之所以还能够访问这个变量,是因为内部函数的作用域包含
 * createComparisonFunction()的作用域。 
 * 
 * 当某个函数第一次被调用时,会创建一个执行环境(execution context)及相应的作用域链,并把作用域链赋值
 * 给一个特殊的内部属性(即[Scope])。然后,使后,使用this、arguments和其他命名参数的值来初始化函数的
 * 活动对象(activation object)。但在作用域,外部函数的活动对象始终处于第二位,外部函数的外部函数的
 * 活动对象处于第三位,..直至作用域链终点的全局执行环境。
 * 
 * 
 * 由于闭包会携带包含它的函数的作用域,因此会比其他函数占有用更多的内存。过度使用闭包可能会导致内存占用
 * 过多,所以只在绝对必要时考虑使用闭包。
 */
function createComparisonFunction(propertyName){
	return function(object1,object2){
		var value1=object1[propertyName]; //****
		var value2=object2[propertyName]; //****
		
		if(value1<value2){
			return -1;
		}else if(value1>value2){
			return 1;
		}else{
			return 0;
		}
	}
}

 

 

2:闭包与变量

作用域链的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值 。因为闭包所保存的是整个变量对象、环境,而不是某个特殊的变量

 

/**
 * 闭包与变量
 * 
 * 作用域链的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值 。
 * 因为闭包所保存的是整个变量对象、环境,而不是某个特殊的变量。
 */
function createFunctions(){
	var result=new Array();
	for(var i=0;i<10;i++){
		result[i]=function(){
			return i;
		}
	}
	return result;
}
var funcs=createFunctions();

//每个函数都输出10
for(var i=0;i<funcs.length;i++){
	document.write(funcs[i]()+"<br/>");
}

/**
 *但是可以创建另一个匿名函数强制让闭包的行为条例预期行为。 
 */
function createFunctions(){
	var result=new Array();
	
	for(var i=0;i<10;i++){
		result[i]=function(num){
			return function(){
				return num;
			}
		}(i);
	}
}

 

 

3:匿名函数(模仿块级作用域)

这种技术经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数。一般来说,我们都应该以是少向全局作用域中添加变量和函数。在一个由很多开发人员共同参与的大型应用程序中,过多的全局变量和函数很容易导致命名冲突。而通过创建私有作用域,每个开发人员既可以使用自己的变量,又不必担心搞乱全局作用域。

/**
 *模仿块级作用域 
 * 
 * 这种技术经常在全局作用域中被用在函数外部,从而限制向全局作用域中添加过多的变量和函数。
 * 一般来说,我们都应该以是少向全局作用域中添加变量和函数。在一个由很多开发人员共同参与
 * 的大型应用程序中,过多的全局变量和函数很容易导致命名冲突。而通过创建私有作用域,每个
 * 开发人员既可以使用自己的变量,又不必担心搞乱全局作用域。
 */

(function(){
	//这里是块级作用域
})()
//无论什么地方,只要临时需要一些变量,就可以使用私有作用域。
function outputNumbers(count){
	(function(){
		for(var i=0;i<count;i++){
			alert(i);
		}
	})()
	
	alert(i);  //导致一个错误。
}

/**
 *这段代码在全局作用域中,其中变量now现在是匿名函数中的局部变量,而我们不必在全局作用域中创建它。
 * 这种做法可以减少闭包占用的内存问题,因为没有指向匿名函数的引用,只要函数执行完毕,就可以立即
 * 销毁其作用域了。 
 */
(function(){
	var now=new Date();
	if(now.getMonth()==0 && now.getDate()==1){
		alert("Happy new year!");
	}
})

 

 

 

4:模块模式

道格拉斯所说的模块模式(module pattern)是为单例创建私有变量和特权方法。 这种模式在需要对单例进行某些初始化,同时又需要维护其私有变量时非常有用。

/**
 *模块模式 
 * 道格拉斯所说的模块模式(module pattern)是为单例创建私有变量和特权方法。
 * 这种模式在需要对单例进行某些初始化,同时又需要维护其私有变量时非常有用。
 */
var singleton=function(){
	//私有变量和私有函数
	var privateVariable=10;
	
	function privateFunction(){
		return false;
	}
	
	//特权、公有方法和属性
	return {
		publicProperty:true,
		
		publicMethod:function(){
			privateVariable++;
			return privateFunction();
		}
	}
}


/**
 *增强的模块模式 
 * 这种增强的模块模式适合那些单例必须是某种类型的实例,同时还必须添加某些属性和方法对其以增强的情况。
 */
var singleton=function(){
	
	//私有变量和私有函数
	var privateVariable=10;
	
	function privateFunction(){
		return false;
	}
	
	//创建对象
	var object=new CustomType();
	
	//添加特权/公有属性和方法
	object.publicProperty=true;
	
	object.publicMethod=function(){
		privateVariable++;
		return privateFunction();
	};
	//返回这个对象
	return object;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值