一、先简单介绍下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