JavaScript中的arguments对象暗藏玄机...原来是我傻了?

一、先简单介绍下JavaScript的arguments

JavaScript中的arguments对象是函数执行时创建的对象。通过它,我们可以动态取参数。学过Java的朋友可能知道方法形参类型可以为:  类型... 形参名,例如:

class Test{
	public static void dynamicParameter(String... arguments){
		for (int i = 0; arguments!=null && i < arguments.length; i++) {
			System.out.println(arguments[i]);
		}
	}
	public static void main(String[] args) {
		dynamicParameter("A","B","C");//依次打印 A B C
		dynamicParameter("A","B","C","D","E");//依次打印 A B C D E
	}
}

通过...的这种方式,可以传递任意个String类型的对象。

而JavaScript中则可以通过arguments对象来实现Java的...

<script type="text/javascript">
function dynamicParameter(arg1){
	alert(dynamicParameter.length);//这个表示函数原型上声明了几个参数 function dynamicParameter(arg1)
	alert(dynamicParameter.arguments.length);//这表示实际传进来几个参数
	//上一行代码可以省略dynamicParameter:
	//alert(arguments.length);//这表示实际传进来几个参数
	for(var i=0;i<arguments.length;i++){//
		alert(arguments[i]);
	}
}
dynamicParameter("A","B","C");//依次弹出 A B C
dynamicParameter("A","B","C","D","E");//依次弹出 A B C D E
</script>

二、暗藏的玄机????

事情的经过是这样的:此前我为公司封装了一系列的通用函数。其中有一个是checkAll,用来实现全选的。这个函数功能比较简单。一开始时这么定义的:

<!DOCTYPE html>
<html>
  <head>
    <title>arguments.html</title>
	
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
	<script type="text/javascript">
		/**
		 * checkAll
		 */
		function checkAll(obj,checkboxname){
			var checkboxes = document.getElementsByName(checkboxname);
			for(var i=0;i<checkboxes.length;i++)
				checkboxes[i].checked = obj.checked;
		}
	</script>
  </head>
  
  <body>
    <input type="checkbox" οnclick="checkAll(this,'hobby');">全选<br>
    <input type="checkbox" name="hobby">编程<br>
    <input type="checkbox" name="hobby">音乐<br>
    <input type="checkbox" name="hobby">篮球<br>
    <input type="checkbox" name="hobby">游戏<br>
  </body>
</html>
即当点击全选按钮的时候,把全选的这个复选框的checked值 赋值给其它name为指定的复选框,然后今天看着函数的时候,觉得不是很简洁,打算利用event.srcElement ,然后只传一个name参数就能实现全选,为了兼容以前的代码。于是写出了如下:

<script type="text/javascript">
		/**
		 * checkAll
		 */
		function checkAll(obj,checkboxname){
			if(arguments.length==1 && typeof(arguments[0])=="string"){//如果只传递了一个参数,并且参数类型为string
				obj = event.srcElement;	//event.srcElement获得触发事件的对象。
				checkboxname = arguments[0];//把传进来的string当作checkboxname
			}
			var checkboxes = document.getElementsByName(checkboxname);
			for(var i=0;i<checkboxes.length;i++)
				checkboxes[i].checked = obj.checked;
		}
	</script>
  </head>
  
  <body>
    <input type="checkbox" οnclick="checkAll(this,'hobby');">全选<br>
    <input type="checkbox" name="hobby">编程<br>
    <input type="checkbox" name="hobby">音乐<br>
    <input type="checkbox" name="hobby">篮球<br>
    <input type="checkbox" name="hobby">游戏<br>
    <input type="checkbox" οnclick="checkAll('loves');">全选<br>
    <input type="checkbox" name="loves">编程<br>
    <input type="checkbox" name="loves">音乐<br>
    <input type="checkbox" name="loves">篮球<br>
    <input type="checkbox" name="loves">游戏<br>
  </body>
一切似乎是这么的美好...但是悲剧发生了。。。。。。。没有效果,于是我一步一步的测试

测试1:

function checkAll(obj,checkboxname){
	alert(arguments[0]);//当我checkAll('loves');这么调用的时候,这里确实的弹出了loves
	if(arguments.length==1 && typeof(arguments[0])=="string"){
		obj = event.srcElement;	
		checkboxname = arguments[0];
	}
	var checkboxes = document.getElementsByName(checkboxname);
	for(var i=0;i<checkboxes.length;i++)
		checkboxes[i].checked = obj.checked;
}

测试2:

function checkAll(obj,checkboxname){
	if(arguments.length==1 && typeof(arguments[0])=="string"){
		alert(arguments[0]);//checkAll('loves'); 这里调用时,也是弹出的loves
	 	obj = event.srcElement;<span>	</span>
	 	checkboxname = arguments[0];
	}
	var checkboxes = document.getElementsByName(checkboxname);
	for(var i=0;i<checkboxes.length;i++)
		checkboxes[i].checked = obj.checked;
}

百思不得其解....

测试3:

function checkAll(obj,checkboxname){
	if(arguments.length==1 && typeof(arguments[0])=="string"){
		obj = event.srcElement;	
		alert(typeof(arguments[0]));//然后我很傻的这么写了一句代码,结果。。你们猜发生了什么??这里弹出了object
		checkboxname = arguments[0];
	}
	var checkboxes = document.getElementsByName(checkboxname);
	for(var i=0;i<checkboxes.length;i++)
		checkboxes[i].checked = obj.checked;
}

我不相信自己的眼睛。。。于是

测试4:

function checkAll(obj,checkboxname){
	alert(arguments.length==1 && typeof(arguments[0])=="string");//true
	if(arguments.length==1 && typeof(arguments[0])=="string"){
		alert(arguments.length==1 && typeof(arguments[0])=="string");//true
		obj = event.srcElement;	
		alert(arguments.length==1 && typeof(arguments[0])=="string");//false
		checkboxname = arguments[0];
	}
	var checkboxes = document.getElementsByName(checkboxname);
	for(var i=0;i<checkboxes.length;i++)
		checkboxes[i].checked = obj.checked;
}
这个时候。。。我突然想给自己一巴掌...我没有聪明一世,但是却糊涂了...囧

对于这个函数来说obj 与 arguments[0]它们所引用的对象其实是一个,只是不同方式的获取罢了。

那么当checkAll('loves')时,一开始obj与arguments[0] 都是loves   后来通过obj = event.srcElement;后    obj与arguments[0]指向的其实是全选的那个checkbox DOM对象了。

我有点想当然了...囧...囧...囧




为什么发表2次不成功0 0




相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页