看板 Ajax 關於我們 聯絡資訊
※ 引述《s25g5d4 (死城盜賊)》之銘言: : 昨天研究了一下一本書 : 征服javascript : 對其中的this與函數作用域以及fn.call()很有興趣 : 就寫出了這個函數 其實覺得好像刻意為了寫this跟call多繞了幾圈耶 XD 而且我不太瞭解為什麼要特地弄個this.a, 其實弄成接回傳值就好啦。XD : if(!document.getElementsByClassName) { : document.getElementsByClassName=function(classN) { //用運算式創立函數 : var tag=this.firstChild; //this指向document : this.a=(this==document? [] : null); //每次從外部呼叫函數時 : do{ //清空陣列 : if(tag.hasChildNodes()) { : document.getElementsByClassName.call(tag,classN); : /* : *fn.call(a,arg)將會執行fn()並使fn()的作用域改為a arg則是參數 : *簡單的說就是this將會指向到tag : */ : } : if(tag.className==classN) : document.a.push(tag); : tag=tag.nextSibling; : }while(tag); : return document.a; : }; : } 我先把 getElementsByClassName 先換個名字, 弄個基礎測試環境是這個板本 http://fiddle.jshell.net/wWhQY/6/ 第一個版本,把奇怪的 document.a 換成抓遞迴回傳值 http://fiddle.jshell.net/wWhQY/7/ 第二個版本,把難懂的call換掉。(基本上能不用就不用,除非比較直覺) http://fiddle.jshell.net/wWhQY/8/ 第三個版本,把細部的邏輯拆出來,讓主線清楚 http://fiddle.jshell.net/wWhQY/9/ 本來想寫第四個版本,除了綁document原生物件,加綁綁 prototype, 這樣可以更像原生的getElementsByClassName 你可以從任意一個 Element 去取 _getElementsByClassName http://fiddle.jshell.net/wWhQY/10/ 不過測了一下,ie6 不支援從 Element加上prototype function, 所以這個版本就變成firefox only了(但firefox又不需要這東西..XD) : 寫的時候為了document.a搞到焦頭爛額... : 每次執行都要清除一次 那這樣執行到第六行時因為回呼函數也會被清除... : 所以只好改用this.a並加入一個判斷式 當this指向document時就清空this.a : 又因為this指向到document所以此時的this.a等於document.a : 當執行到第六行時的this就會指向到tag 所以這時候的this.a = tag.a所以給null : 因為用不到 當變數值指向null時就會被javascript編譯器回收 : 總之就是錯綜複雜 搞到我也亂了XDDDD : 所以... : IE6 must die! 其實你會覺得很混亂是因為你沒有把flow抓穩, 而全域變數在遞迴時的操作狀態又更為複雜, 這種遞迴呼叫,把flow抓穩是很重要的事情。:p 用至少一個sample去用腦袋逐行執行到底是必要的。 -- 我:一半的日子讓你說,我聽你說你的所有______________________________________ ______________________________________一半的日子我想說,對你說過去的所有:我 _______________________________________________________ 在討論中妥善扮演兼具聆聽與分享的角色,是我們一生的課題。 _______________________________________________________ -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.70.191.115
TonyQ:btw 我覺得fiddle 對firebug不太友善 XD 有人跟我一樣感覺嗎 07/11 23:43
TonyQ:或者應該反過來說,firebug對iframe不太友善。:p 07/11 23:43
s25g5d4:就是..為了用this與call所以故意寫的@@ 我是覺得用傳值 07/12 00:06
s25g5d4:如果有人居心不良的話就爆了@@ 07/12 00:06
s25g5d4:一開始的想法就是去抓arguments[1] 07/12 00:07
grence:開發還是用firebug,jsFiddle只是為了找個 host..測IE XD 07/12 00:12
TonyQ:this/call 一樣可以因為居心不良而爆啊..XD 07/12 00:37
TonyQ:再說,其實只要把函式隱藏起來,外面調用不到就很安全.. 07/12 00:38
adamp3:fiddle真的滿不錯的啊 07/12 00:41