一、先簡單介紹下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 CdynamicParameter("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 CdynamicParameter("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" onclick="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"){//如果只傳遞了一個參數,並且參數類型為stringobj = 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" onclick="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" onclick="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');這麼調用的時候,這裡確實的彈出了lovesif(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]));//然後我很傻的這麼寫了一句代碼,結果。。你們猜發生了什嗎??這裡彈出了objectcheckboxname = 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");//trueif(arguments.length==1 && typeof(arguments[0])=="string"){alert(arguments.length==1 && typeof(arguments[0])=="string");//trueobj = event.srcElement;alert(arguments.length==1 && typeof(arguments[0])=="string");//falsecheckboxname = 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