前端面试题——js闭包

什么是闭包?以下代码点击<p> 会输出什么?为什么?能大概说明白的话继续问能想出几种解决办法。

==========

出错:获取HTML元素集合,循环给元素添加事件。在事件响应函数中(event handler)获取对应的索引。但每次获取的都是最后一次循环的索引。 

出错原因:初学者并未理解JavaScript的闭包特性。通过element.onclick=function(){alert(i);}方式给元素添加点击事件。响应函数function(){alert(i);}中的 i 并非每次循环时对应的 i(如0,1,2,3,4)而是循环后最后 i 的值5。 或者说循环时响应函数内并未能保存对应的值 i,而是最后一次i++的值5。 

解决方法:见html代码注释部分


<!DOCTYPE HTML> 
<html> 
<head> 
<meta charset="utf-8" /> 
<title>闭包演示</title> 
<style type="text/css"> 
    p {background:gold;}  
</style> 
<script type="text/javascript">   
/* 网上的七种方法

//将变量 i 保存给在每个段落对象上
function init() {      
    var pAry = document.getElementsByTagName("p");      
    for( var i=0; i<pAry.length; i++ ) {  
    	 pAry[i].i=i;	    
         pAry[i].onclick = function() {      
         alert(this.i);      
    }   
  }  
}

//将变量i保存在匿名函数自身
function init(){
	var pAry=document.getElementsByTagName("p");
	for (var i = 0; i <pAry.length; i++) {
		(pAry[i].onclick=function(){
		alert(arguments.callee.i)
		}).i=i;
	};
}  


//加一层闭包,i以函数参数形式传递给内层函数
function init(){
	var pAry=document.getElementsByTagName("p");
	for (var i = 0; i < pAry.length; i++) {
		(function(arg){
			pAry[i].onclick=function(){
				alert(arg);
			};
		})(i);//调用时参数
	};
}


//加一层闭包,i 以局部变量形式传递给内层函数 
function init(){
	var pAry=document.getElementsByTagName("p");
	for (var i = 0; i < pAry.length; i++) {
		(function(){
			var temp=i;//调用时局部变量
			pAry[i].onclick=function(){
				alert(temp);
			}
		})();
	};
}



//加一层闭包,返回一个函数作为响应事件
function init(){
	var pAry=document.getElementsByTagName("p");
	for (var i = 0; i < pAry.length; i++) {
		pAry[i].onclick=function(arg){
			return function(){
				alert(arg);
			}
		}(i);
	};
}



function init(){
	var pAry=document.getElementsByTagName("p");
	for (var i = 0; i < pAry.length; i++) {
		pAry[i].onclick=new Function("alert("+i+");");//new一次就产生一个函数实例

	};
}

function init(){
	var pAry=document.getElementsByTagName("p");
	for (var i = 0; i < pAry.length; i++) {
		pAry[i].onclick=Function("alert("+i+");");

	};
}

*/
function init() { 
	var pAry = document.getElementsByTagName("p"); 
	for( var i=0; i<pAry.length; i++ ) { 
		pAry[i].onclick = function() { 
			alert(i); 
		} 
	} 
} 

</script>   
</head>   
<body onload="init();">   
<p>产品 0</p>   
<p>产品 1</p>   
<p>产品 2</p>   
<p>产品 3</p>   
<p>产品 4</p>   
</body>   
</html> 


前端面试题——js闭包,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。