Ajax 板


LINE

雖然跟原po問題無關 但好像有人對為什麼 function my_function(){ do some stuff } 這種寫法不好感到好奇 在網路上 這篇文章有很詳細的解釋 http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/ 但可能大家懶得看英文 所以看看我能不能解釋一下 可能有點長.. 首先js裡有一個東西 叫做hoisting 意思就是"提起來" "拉起來" 那到底是拉甚麼東西哩? 當我們作一個declaration 被browser解讀時 他會自動被放到他context的最上面 比如說: (function(){ alert(my_var); var my_var = 'say something man'; })(); 這裡不會產生js的ReferenceError 因為在 interpreter 眼裡是長這樣 (function(){ var my_var = undefined; alert(my_var); my_var = 'say something man'; })(); my_var已經被定義了(雖然是assign "undefined" object) 所以firebug裡不會看到 ReferenceError: my_var is not defined 那這和function有甚麼關係哩 比較以下兩例: (function(){ my_func(); var my_func= function(){ alert('yo'); }; })(); (function(){ my_func(); function my_func(){ alert('yo'); }; })(); 第一個會有 TypeError: my_func is not a function 第二個則會跑出"yo" 因為他被解讀為 (function(){ var my_func = undefined; my_func(); my_func= function(){ alert('yo'); }; })(); (function(){ function my_func(){ alert('yo'); }; my_func(); })(); 有看到差異了嗎? 在hoisting中 declaration會被整個搬上去 而var xx = function yy(){};這種寫法 只有左邊的部分是declaration 所以搬上去時 右邊不見了 這意味著甚麼呢? function yy(){};這種寫法 在同一個context裡 不管你寫在哪 全部都呼叫的到 和順序無關 有人會說 這超好的呀 網路script就是要隨便寫都通 要forgiving一點 這當然沒錯 就像var就有變數 管他甚麼型別 但是其實這種code在維護上有很大的缺點 1. 這某種層度像是種變數汙染 感覺還沒寫過的東西 上面卻叫得出來 或是不小心用到了同樣名字 會產生難預料又難debug的問題 2. Overwrite問題: (function(){ function sayHelloThenHi(){ alert('hello'); } sayHelloThenHi(); function sayHelloThenHi(){ alert('hi'); } sayHelloThenHi(); })(); 這會有甚麼結果呢? 他會跟你講兩聲hi 直觀上這是我們想要的嗎? (function(){ var sayHelloThenHi=function(){ alert('hello'); } sayHelloThenHi(); sayHelloThenHi = function(){ alert('hi'); } sayHelloThenHi(); })(); 此例中 他會先說hello在說hi 感覺似乎是我們比較想要的結果 至於為什麼? 相信你已經知道了 結論: 那到底要怎麼寫function比較好呢 1. 如果你JAVA或是C#等等classical的語言實在太強了 為什麼要為js這種詭異的prototypal語言改習慣?? 那千萬記住把function xxx(){}這種東西寫在每個context的最前面 這就可以省掉大部分錯誤和麻煩 (這也就是很多js的書說宣告變數要在最前面) 2. 如果你想鑽研js這詭異的語言 你的function應該大部分會出現在你global abatement的object下面 如 var MySite = { my_awesome_func : function(){ //do something good } }; MySite.my_awesome_func(); //invoke 或是expression的寫法 var callback = function(){ do some useful stuff }; 這常常用於callback的傳遞... 總之你應該不會有機會寫 function bad(){ //still do something } 這種東西 真是抱歉 講太多廢話了.. 一打就很難停下來.. 因為國內有少數教材 常會有不是很正確的觀念 讓我以前剛學習時 走了不少冤枉路 以至於看到種觀念有關的東西 我就特別想講 加上js又是很特別的語言 常常有人用其他語言的邏輯來套 但事實上含意是不同的 希望有人有耐心可以看到這裡 如果有錯誤 也希望可以指正:D ※ 引述《senser (彷彿曾經一起死過)》之銘言: : 您可能對於js的function宣告方式沒有很清楚 : 但我想可能很多人也有不正確的認識 : js的function宣告方式分為兩種 : function declaration和function expressions : 主要會因為hoisting 而有些微的不同 : invoke的方式 大概分為四種 : 主要和this的binding有關 : 在這例子中 您的設計想法是完全可行且合理的 : 只是實做上要注意 : 首先如果你加了() 就是一種invocation : 意思就是執行這function : 所以應該寫成 : $(selector).mousedown(function(){ : if(using IE){ : func1(); //invoke : }else { : func2(); //invoke : } : }); : 如果你不直接invoke : 應該用function expression : 因為functon declaration絕不應出現在{}block中 : 在if中作function declaration : 每個browser對這種錯誤會有不同的奇怪詮釋 : (新的browser supports 所謂的 function statement) : 再者也有可能因為hoisting而overwrite的問題產生 : if(using IE){ : var myHandler = func1; : }else { : var myHandler = func2; : } : $(selector).mousedown(myHandler); //function copying : 有興趣可以參考這兩篇 : http://kangax.github.com/nfe/ : http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/ : ※ 引述《coldollsheep (加油加油^^)》之銘言: : : 不好意思 問一個比較粗淺的問題 : : 我做了一個按鈕 點了會有聲音 : : IE 跟其他瀏覽器是採用不同的方法 : : 如以下程式碼 : : 可以看到我毎次點擊都必須判斷一次 : : //關鍵那顆鈕 : : $('#click_btn').mousedown(function (ev) : : { : : //1.處理音效 : : if ($.browser.msie) : : { : : document.getElementById("soundeffect").src=soundfile; : : } else : : { : : var _audio2 = document.createElement('audio') ; : : _audio2.src = soundfile ; : : _audio2.play() : : } : : } : : ---- : : 有沒有辦法變成這樣 : : func1() : : { : : 實際內容 : : } : : func2() : : { : : 實際內容 : : } : : //1.處理音效 : : if ($.browser.msie) : : { : : playsound() = func1(); <------這裡就是關鍵 我不知道怎麼弄這裡 : : 觀念不好不好意思 : : } else : : { : : playsound() = func2(); : : } : : //關鍵那顆鈕 : : $('#click_btn').mousedown(function (ev) : : { : : //1.處理音效 : : playsound(); : : } --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 71.104.219.9 ※ 編輯: senser 來自: 71.104.219.9 (09/21 13:23)
1F:推 mrbigmouth:推清楚明白 尤其是當你需要讓function的內容依情況而有 09/21 14:30
2F:→ mrbigmouth:所改變時 一定不能用function xxx()的寫法 09/21 14:30
3F:推 ChowMein:簡單說就是 var 和 function declaration 的差異 09/21 18:33
4F:推 tcling:寫的太好了! 09/22 13:39
5F:推 No:好文~ 09/22 18:28
6F:→ tyf99:我是把 var=func() 當做是 function pointer 09/22 19:03
7F:→ tyf99:C 會有重複宣告錯誤,js 重複宣告是後面的宣告會覆蓋前面的 09/22 19:05







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:WOW站內搜尋

TOP