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