亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊(cè) 查看新帖 |

Chinaunix

  平臺(tái) 論壇 博客 文庫(kù)
最近訪問(wèn)板塊 發(fā)新帖
查看: 2227 | 回復(fù): 0
打印 上一主題 下一主題

JavaScript中function的動(dòng)態(tài)執(zhí)行 [復(fù)制鏈接]

論壇徽章:
0
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2010-12-17 13:24 |只看該作者 |倒序?yàn)g覽
轉(zhuǎn):村長(zhǎng)筆記
JavaScript中function的動(dòng)態(tài)執(zhí)行



由于最近來(lái)自重構(gòu)中的需要,所以深入的研究了JavaScript中function(函數(shù)/方法)的動(dòng)態(tài)執(zhí)行。搜索了一下,發(fā)現(xiàn)在網(wǎng)上詢問(wèn)相關(guān)問(wèn)題的人非常多,相應(yīng)給出的解決方法也是很多的,但卻沒(méi)有深入研究的說(shuō)明。本人覺(jué)得深入的研究并解決function的動(dòng)態(tài)執(zhí)行問(wèn)題還是非常有價(jià)值的。



本文將從不同的應(yīng)用情況入手,并由淺入深的給出解決方案與分析。動(dòng)態(tài)執(zhí)行從服務(wù)端返回的JavaScript代碼不在本文的討論范圍內(nèi)。



場(chǎng)景1:動(dòng)態(tài)執(zhí)行無(wú)參數(shù)、無(wú)返回值function

這是最簡(jiǎn)單,也是最常見(jiàn)的case。這種場(chǎng)景下,使用eval或者setTimeout都是可以的。如下示例代碼:
  1. function test() {  

  2.     alert('test');  

  3. }  

  4.    

  5. eval("test()");  

  6. setTimeout("test()", 0);

復(fù)制代碼
由于這種case是最簡(jiǎn)單的,如何去執(zhí)行參考示例即可。想多做一點(diǎn)說(shuō)明的是setTimeout這個(gè)方法。



對(duì)于目前的JavaScript引擎來(lái)說(shuō),都是單線程處理任務(wù)的(JavaScript engines only have a single thread)。John Resig在他的How JavaScript Timer Work中有詳細(xì)的說(shuō)明,這里不做累述。對(duì)于JavaScript的Timer來(lái)說(shuō),setTimeout與setInterval都是可以異步的執(zhí)行代碼的,但是它們卻在執(zhí)行時(shí)有非常本質(zhì)的區(qū)別(區(qū)別仍可參考How JavaScript Timer Work),被推薦使用的是setTimeout方法。既然setTimeout可以用來(lái)異步執(zhí)行JavaScript的代碼(function),那么我們一旦將它的第二個(gè)參數(shù)設(shè)置為0,即0毫秒后執(zhí)行第一個(gè)參數(shù)內(nèi)容的話,就相當(dāng)于立即異步執(zhí)行代碼。這樣,通過(guò)使用多個(gè)setTimeout方法,便以另一種形式在JavaScript中實(shí)現(xiàn)多線程。



場(chǎng)景2:動(dòng)態(tài)執(zhí)行簡(jiǎn)單類型參數(shù)、無(wú)返回值的function

這個(gè)case雖然要比場(chǎng)景1復(fù)雜一些,但是仍然非常簡(jiǎn)單即可完成。
  1. function test(input) {  

  2.     alert(input);  

  3. }  

  4.    

  5. var t1 = 1;  

  6. eval("test(" + t1 + ")");  

  7. var t2 = true;  

  8. setTimeout("test(" + t2 + ")", 0);
復(fù)制代碼
場(chǎng)景3:動(dòng)態(tài)執(zhí)行復(fù)雜類型參數(shù)、無(wú)返回值的function

這個(gè)也不復(fù)雜,就怕想復(fù)雜了。如果按照?qǐng)鼍?中的方式來(lái)動(dòng)態(tài)執(zhí)行,那么多半你會(huì)比較郁悶,因?yàn)橄雮鬟f復(fù)雜類型的參數(shù)比較困難。簡(jiǎn)單的方式如下:
  1. function test(input) {  

  2.      alert(input[0].name);  

  3. }  

  4.    

  5. var t = [{'name' : 'db'}];  

  6. eval("test(t)");  

  7. setTimeout("test(t)", 0);
復(fù)制代碼
可以看出,只需要將變量直接寫(xiě)到function字符串的參數(shù)部分即可。這種書(shū)寫(xiě)方法比較依賴于既定義的變量,我們改變一下代碼再做一個(gè)測(cè)試,代碼如下:
  1. function test(input) {  

  2.      alert(input[0].name);  

  3. }  

  4.    

  5. function print() {  

  6.      var t = [{'name' : 'db'}];  

  7.      eval("test(t)");  

  8.     setTimeout("test(t)", 0);  

  9. }  

  10.    

  11. print();
復(fù)制代碼
在不同的瀏覽器上,可以看到在eval輸出了一次之后,setTimeout要么是沒(méi)有輸出,要么就是提示說(shuō)“t未定義”。這是因?yàn)閟etTimeout第一個(gè)參數(shù),是存在作用域問(wèn)題。只有在全局作用域定義的函數(shù)和變量,才能被setTimeout使用。這一點(diǎn)一定要注意,如果非要使用非全局的函數(shù)與變量,只有考慮閉包來(lái)實(shí)現(xiàn)。



場(chǎng)景4:動(dòng)態(tài)執(zhí)行有返回值的function
在前邊一些case中,已經(jīng)解決了動(dòng)態(tài)執(zhí)行的function的傳參問(wèn)題,對(duì)于大多數(shù)的開(kāi)發(fā)者來(lái)說(shuō)就已經(jīng)足夠了。但是,在使用JavaScript進(jìn)行基于配置的功能開(kāi)發(fā)時(shí),可能還會(huì)遇到需要?jiǎng)討B(tài)執(zhí)行有返回值function的case。



之前幾個(gè)case中,我們實(shí)現(xiàn)動(dòng)態(tài)執(zhí)行時(shí),使用的是eval與setTimeout?梢蕴崆胺穸ǖ氖莝etTimeout,因?yàn)檫@個(gè)方法已經(jīng)固定了返回值,即當(dāng)前計(jì)時(shí)器的引用,用來(lái)清理計(jì)時(shí)器時(shí)使用。當(dāng)然,提前否定setTimeout讓很多人不甘心,并給出了如下方法得到返回值:

function test(input) {  

     return "result:" + input;  

}  

var t = 'test';  

setTimeout("alert(test(t))", 0);



執(zhí)行后發(fā)現(xiàn),返回值的確被打印了出來(lái)。但是,如果我想使用這個(gè)返回值呢?我們將代碼變化一下:
  1. function test(input) {  

  2.      return "result:" + input;  

  3. }  

  4. var t = 'test';  

  5. var result = '';  

  6. setTimeout("result = test(t)", 0);  

  7. alert(result);
復(fù)制代碼
如果得到最后一行的輸出結(jié)果,所有人都會(huì)失望。前文已經(jīng)提過(guò),setTimeout是異步執(zhí)行的,所以在第一個(gè)參數(shù)中的JavaScript代碼執(zhí)行時(shí),result就已經(jīng)輸出了。顯然,setTimeout要處理這個(gè)問(wèn)題比較苦難。



eval在這個(gè)case中比較給力,能夠完成我們交給的任務(wù):
  1. function test(input) {  

  2.      return "result:" + input;  

  3. }  

  4. var result;  

  5. var t = 'tttt';  

  6. result = eval("test(t)");  

  7. alert(result);  

  8.    

  9. t = '2222';  

  10. eval("result = test(t)");  

  11. alert(result);
復(fù)制代碼
兩種寫(xiě)法均可以得到我們希望的結(jié)果。而且復(fù)雜一些的需要也能勝任:
  1. Test = function() {  

  2. };  

  3. Test.prototype = {  

  4.      test : function(input) {  

  5.          return "result:" + input;  

  6.     }  

  7. };  

  8.    

  9. var te = new Test();  

  10. var result;  

  11. var t = 'tttt';  

  12. result = eval("te.test(t)");  

  13. alert(result);
復(fù)制代碼
還有一種方式,也可以滿足這個(gè)case:
  1. Test = function() {  

  2. };  

  3. Test.prototype = {  

  4.      test : function(input) {  

  5.          return "result:" + input;  

  6.      }  

  7. };  

  8.    

  9. var t = 'tttt';  

  10. var te = new Test();  

  11. var value = new Function("return te.test(t)")();  

  12.    

  13. alert(value);
復(fù)制代碼
但是,new Function的方式卻存在作用域的問(wèn)題,而且也需要借助閉包才能解決。問(wèn)題如下:
  1. Test = function() {  

  2. };  

  3. Test.prototype = {  

  4.      test : function(input) {  

  5.         return "result:" + input;  

  6.      }  

  7. };  

  8.    

  9. function run() {  

  10.     var t = 'tttt';  

  11.     var te = new Test();  

  12.     var value = new Function("return te.test(t)")();  

  13.    

  14.     alert(value);  

  15. }  

  16.    

  17. run();
復(fù)制代碼
而eval就不存在作用域的問(wèn)題:
  1. Test = function() {  

  2. };  

  3.   Test.prototype = {  

  4.   test : function(input) {  

  5.    return "result:" + input;  

  6.   }  

  7. };  

  8.    

  9.    function run() {  

  10.   var te = new Test();  

  11.   var result;  

  12.   var t = 'tttt';  

  13.   result = eval("te.test(t)");  

  14. alert(result);  

  15. }  

  16. run();
復(fù)制代碼
總結(jié):
在處理動(dòng)態(tài)執(zhí)行的問(wèn)題上,推薦使用eval。它是同步處理的,而且無(wú)作用域問(wèn)題,復(fù)雜參數(shù)、返回值均可滿足。
您需要登錄后才可以回帖 登錄 | 注冊(cè)

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號(hào)-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號(hào):11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)會(huì)員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過(guò)ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請(qǐng)注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP