js中this和回调方法循环-我们到底能走多远系列(35)
生活随笔
收集整理的這篇文章主要介紹了
js中this和回调方法循环-我们到底能走多远系列(35)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
我們到底能走多遠系列(35)
扯淡:
13年最后一個月了,你們在13年初的計劃實現了嗎?還來得及嗎?
請加油~
?
主題:
最近一直在寫js,遇到了幾個問題,可能初入門的時候都會遇到吧,總結下。
例子: var x =9; var fobj ={x:1,test:function(callback){var x= 2;callback();} } function pp(){var x = 3;fobj.test(function(){alert(this.x)//9 }) } pp(); 上面這段代碼打印出的是 9 ,可以看到test的調用者是fobj,可是在test中執行回調時callback();這調代碼前面是空的。所以其實是有一個作為的全局調用了這個回調,所以,執行回調代碼時的this則就是全局環境。 總結一下:當方法被一個對象調用的時候:fobj.test(),那么this是綁定在fobj上的。 如果不是這樣調用:callback() 那么this則綁定在全局變量上。 回調函數中的this,最好不要使用,因為this指的是,調用函數的那個對象。 回調函數作為參數傳入一個方法,我們就不能確定這個方法中的環境變量是怎樣了的。 Function的bind方法: var x =9; var fobj ={x:1,test:function(callback){var x= 2;callback();} } function pp(){var x = 3;fobj.test(function(){alert(this.x)//1 }.bind(fobj)) } pp(); 使用bind方法后輸出為1,其中的this指向了fobj。 Array的forEach方法 在使用forEach方法的時候,也有類似的場景,這個方法提供了參數傳入指定的上下文 例子: var x = "test"; var ojb = {x : "obj" } function pp(){var t = [1,2,3,4];t.forEach(function(value,index){alert(this.x + value);},ojb); } pp(); 以上代碼就指定了forEach中第一個參數匿名函數的上下文為ojb。 詳細的參數規則和方法使用教程:摸我 循環回調函數問題: 例子: for(var i=1;i<4;i++){doCallBack(function(){alert(i);//1,2,3 }); }function doCallBack(callback){var x = "callback";callback(); } 上面的代碼執行結果看似沒有問題,在實際項目中,使用回調異步一些耗時工作,比如數據庫的查詢,寫node的時候這種情況很多,那么會出現什么樣的結果呢? 看下下面的模擬: for(var i=1;i<4;i++){doCallBack(function(){setTimeout(function(){alert(i);},1000)//4,4,4 }); }function doCallBack(callback){var x = "callback";callback(); } ?????全部打印4,導致這個發生的原因是因為回調函數中的耗時工作是異步的,也就是說第一次循環執行到doCallBack的時候,直接跳到for的末尾,然后開始第二次循環,一次類推,當循環達到i的最大值4的時候跳出循環,而延遲的工作開始了,這時候他們打印i,而這個i被加到了4,所以就有了全部打印4的結果。 先理解下js中的作用域鏈,比如下面的代碼型式: function A(){var i =1;function B(){i =2;...} } function C(){...} ?????B方法的作用域鏈就像這樣 B內部 ->A內部 ->全局,也就是說方法內部的方法是可以引用到外部方法的變量的,如果這個B方法在C被調用,那么我們就實現C方法使用到了同級方法的作用域。其實我們就會認為這是一個閉包的行為。這樣的作用域鏈機制,帶來的副作用在前面提到的例子中展示了。 解決辦法:? for(var i=1;i<4;i++){(function(x){doCallBack(function(){// alert(x)setTimeout(function(){alert(x);},1000);//1,2,3 });})(i) }function doCallBack(callback){callback(); } ?????這里我們可以看到加了個匿名方法包在外面然后直接傳入i,執行方法。還利用了這個i作為基本類型是按值傳遞的,所以在函數內部是一個復制的值,外部i的自增將不能改變內部函數的x的值了。 也可以寫成這樣: for(var i=1;i<4;i++){!function(x){doCallBack(function(){// alert(x)setTimeout(function(){alert(x);},1000);//1,2,3 });}(i) }function doCallBack(callback){callback(); } 用遞歸的辦法:感受下 function doCallBack(x){if(x<=1){return 1;}else{setTimeout(function(){alert(x);},1000);//4,3,2return doCallBack(x-1);}} doCallBack(4)?
實際應用中,遇到引用類型的時候,展示使用里很土的辦法先解決一下 代碼類似:(3次循環,修改成下面代碼) var rstScoreMsg0 = {score : scores[0],username : uids[0],expLoser : expLoser,expWinner : expWinner,uid : 0};var rstScoreMsg1 = {score : scores[1],username : uids[1],expLoser : expLoser,expWinner : expWinner,uid : 0};var rstScoreMsg2 = {score : scores[2],username : uids[2],expLoser : expLoser,expWinner : expWinner,uid : 0};recordUser(rstScoreMsg0);recordUser(rstScoreMsg1);recordUser(rstScoreMsg2); 理論上,通過對象復制也是可行的。讓我們繼續前行
----------------------------------------------------------------------
努力不一定成功,但不努力肯定不會成功。轉載于:https://www.cnblogs.com/killbug/p/3457445.html
總結
以上是生活随笔為你收集整理的js中this和回调方法循环-我们到底能走多远系列(35)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 千万青年学子,双击电子版微积分
- 下一篇: Java 网络编程(二) 两类传输协议: