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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

闭包用法:经典案例

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

閉包用法:經典案例

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

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

獲取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>

??????????????????????????? //這里重復5<tr>,結構和上面一樣

?????????????????? </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()這個函數就被執行。myEffect做的事情很簡單,它給每一個tr標簽都添加了3個事件監聽函數:onmouseroveronmouseoutonclick。前兩個函數非常簡單,無須解釋。亮點在于第3個函數:

?

tr.οnclick=(function(){

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

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

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

???????? }

})();

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

tr.οnclick= function(){

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

};

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

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

模擬多線程

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工具,用來創建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);

???????? }

?

???????? //工具函數,添加線程

???????? 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所執行的函數中,可以一直訪問外層函數中的局部變量num

?

——本段文字節選自《EXT江湖》

圖書詳細信息:

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。