日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

闭包用法:经典案例

發(fā)布時間:2024/4/15 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 闭包用法:经典案例 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

閉包用法:經(jīng)典案例

學(xué)習(xí)一樣技能,最終是想把它投入運用。我們從JS函數(shù)的最基礎(chǔ)用法,一直研究到作用域鏈、閉包,這個過程消耗了我們大量的心血,那么閉包到底能用在哪些場景里面呢?下面將使用逐個枚舉的方式給出運用閉包的典型戰(zhàn)例。

請注意,以下的例子都是應(yīng)用閉包的典型場景,當(dāng)然如果你愿意,也可以把它叫做“代碼模式”。深入理解,甚至記住這些場景,將會讓你的閉包技法如有神助。

獲取Table中被點擊的行

4.53

代碼:

<html>

???????? <title>Ext江湖</title>

???????? <meta http-equiv="Content-Type" content="text/html" ; charset="utf-8">

???????? <script type="text/javascript" src="closure_example.js"></script>

???????? <body οnlοad="myEffect()">

?????????????????? <table id="mytab" border="1">

??????????????????????????? <tr>

???????????????????????????????????? <td>1</td>

???????????????????????????????????? <td>2</td>

???????????????????????????????????? <td>3</td>

???????????????????????????????????? <td>4</td>

???????????????????????????????????? <td>5</td>

??????????????????????????? </tr>

??????????????????????????? <tr>

???????????????????????????????????? <td>1</td>

???????????????????????????????????? <td>2</td>

???????????????????????????????????? <td>3</td>

???????????????????????????????????? <td>4</td>

???????????????????????????????????? <td>5</td>

??????????????????????????? </tr>

??????????????????????????? //這里重復(fù)5<tr>,結(jié)構(gòu)和上面一樣

?????????????????? </table>

?????????????????? <div id="console" style="background:#ffff00"></div>

???????? </body>

</html>

closure_example.js的代碼如下:

function myEffect(){

???????? var console=document.getElementById('console');

???????? var tab=document.getElementById('mytab');

???????? var trs=tab.getElementsByTagName('tr');

???????? for(var i=0;i<trs.length;i++){

?????????????????? var tr=trs[i];

?????????????????? tr.οnmοuseοver=function(){

??????????????????????????? this.style.background="#ff0000";

?????????????????? }

?????????????????? tr.οnmοuseοut=function(){

??????????????????????????? this.style.background="#ffffff";

?????????????????? }

?????????????????? tr.οnclick=(function(){

??????????????????????????? var rowNum=i;

??????????????????????????? return function(){

???????????????????????????????????? console.innerHTML="點擊了第"+rowNum+"";

??????????????????????????? }

?????????????????? })();

???????? }

}

解析:

因為有這一句<body οnlοad="myEffect()">,所以在body加載完成之后,myEffect()這個函數(shù)就被執(zhí)行。myEffect做的事情很簡單,它給每一個tr標簽都添加了3個事件監(jiān)聽函數(shù):onmouseroveronmouseoutonclick。前兩個函數(shù)非常簡單,無須解釋。亮點在于第3個函數(shù):

?

tr.οnclick=(function(){

???????? var rowNum=i;

???????? return function(){

?????????????????? console.innerHTML="點擊了第"+rowNum+"";

???????? }

})();

從整體看,這是一個“自執(zhí)行”函數(shù),最終被注冊給onclick事件的是內(nèi)部return的這個匿名函數(shù)。那么,為什么要這么做呢?比如,和上面兩個函數(shù)一樣,做成這樣可不可以呢?

tr.οnclick= function(){

???????? console.innerHTML="點擊了第"+i+"";

};

注意,i是外層那個for循環(huán)里面定義的循環(huán)變量。你可以自己測試這個代碼,最終結(jié)果是:無論你點擊哪一行,結(jié)果都是“點擊了第6行”。那么為什么會出現(xiàn)這種結(jié)果呢?這是因為在for循環(huán)的過程中,i始終代表的是同一個變量。雖然你看似給每個tr都注冊了一個onclick函數(shù),但是里面那個i最終指向的是同一個東西,它是隨著for循環(huán)變化的。所以,在for循環(huán)結(jié)束之后,i將會一直是6。那么如何在for循環(huán)結(jié)束之后,讓i一直保留for循環(huán)中對應(yīng)的次序呢?這就是上面那個return函數(shù)的作用了。里面用一個局部變量var rowNum=i;i的值“緩存”起來,然后即使外層的“自執(zhí)行”函數(shù)退出,內(nèi)部return出來的匿名函數(shù)仍然可以訪問到對應(yīng)順序的值。

有了本章第3節(jié)對函數(shù)“作用域鏈”的研究,rowNum這個外層函數(shù)的局部變量被緩存在哪里,這種技法為什么能起作用,就無須多言了吧?

模擬多線程

4.54

HTML代碼:

<html>

???????? <title>模擬多線程</title>

???????? <meta http-equiv="Content-Type" content="text/html" ; charset="utf-8">

???????? <body>

?????????????????? <button name="添加線程" value="添加線程" οnclick="addThread()">添加

??????????????????????????? 線程</button>

???????? </body>

???????? <script type="text/javascript" src="sim_thread.js"></script>

</html>

腳本代碼:

//這里是一個簡單的DIV工具,用來創(chuàng)建DIV

function DivUtil(){}

???????? DivUtil.prototype.counter=0;

???????? DivUtil.prototype.creatDiv=function(){

?????????????????? var div=document.createElement('div');

?????????????????? div.style.background='#ffff00';

?????????????????? div.id=this.counter++;

?????????????????? document.body.appendChild(div);

?????????????????? return div;

???????? }

???????? var divUtil=new DivUtil();

?

???????? //這里是“線程”類

???????? Thread=function(){}

???????? Thread.prototype.start=function(){

?????????????????? var div=divUtil.creatDiv();

?????????????????? if(div.id>=10){

??????????????????????????? div.innerHTML="只允許起10個線程,看看你的CPU,撐到爆!";

??????????????????????????? return;

?????????????????? }

?????????????????? var num=div.id;

?????????????????? setInterval(function(){

??????????????????????????? div.innerHTML=""+div.id+"個線程運行中..."+(num++);

?????????????????? },50);

???????? }

?

???????? //工具函數(shù),添加線程

???????? function addThread(){

?????????????????? var thread=new Thread();

?????????????????? thread.start();

???????? }

運行效果如圖4-91所示。

?

4-91? 模擬多線程

解析:

這是一個非常有趣的例子,看起來就像啟動了多個“線程”,核心的代碼是這段:

var num=div.id;

setInterval(function(){

???????? div.innerHTML=""+div.id+"個線程運行中..."+(num++);

},50);

因為閉包的緣故,在定時器setInterval所執(zhí)行的函數(shù)中,可以一直訪問外層函數(shù)中的局部變量num

?

——本段文字節(jié)選自《EXT江湖》

圖書詳細信息:

http://www.cnblogs.com/broadview/archive/2012/01/20/2327735.html

總結(jié)

以上是生活随笔為你收集整理的闭包用法:经典案例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。