那些年一起過的JS閉包,作用域恨溜,this

之前有寫過閉包符衔,作用域,this方面的文章糟袁,但現(xiàn)在想想當(dāng)時寫的真是廢話太多了判族,以至于繞來繞去的,讓新手反而更難理解了项戴,所以就有了此篇文章形帮,也好和閉包,作用域周叮,this告一段落辩撑。

第一個問題:什么是閉包?

我不想回答這個問題仿耽,但是我可以告訴你的是**閉包可以解決函數(shù)外部無法訪問函數(shù)內(nèi)部變量的問題**合冀。下面是一段沒有使用閉包的代碼:

function fn(){

var a = 10;

}

 alert(a);

 //報錯了,因為a沒有定義项贺,雖然函數(shù)fn里面定義了a但是君躺,但是它只能在函數(shù)fn中使用。也就是作用域的問題开缎。

再看‘閉包可以解決函數(shù)外部無法訪問函數(shù)內(nèi)部變量的問題’這段話棕叫,好像有點意思,那么究竟閉包是怎么做的奕删,看下面代碼谍珊。

function fn(){

    //定義了一個變量name

var name = '追夢子';

    //我現(xiàn)在想在外部訪問這個變量name怎么辦呢?哈:不是有return,我把它返回出去砌滞,我再用個變量接收一下不就可以了侮邀,哈哈哈哈~~~~~

     return name;

  }

  var name = fn();//接收fn返回的name值。

  alert(name);//追夢子贝润;
 ·······這里的閉包就是利用函數(shù)的return绊茧。除了通過return還可以通過其他的幾種方法如下:

方法1:

function fn(){
  var a = 0;
  b = a;
}
alert(b)

這里利用了js的一個特性,如果在函數(shù)中沒有用var定義變量打掘,那么這個變量屬于全局的华畏,但這種方法多少有些不好。

方法2:

var f = null;
function fn(){
  var a = 0;
  f = function(){
    a++;
    f.a = a;
  };
}
fn();
f();
alert(f.a);//1
f();
alert(f.a);//2

但好像也沒有那樣神奇對吧尊蚁?其實閉包還有一個很重要的特性亡笑。來看一個例子。

var lis= document.getElementsByTagName['li'];

//假如這段代碼中的lis.length = 5;

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

lis[i].onclick = function(){

alert(i);

};

 }

最終結(jié)果是不管單擊哪個li元素都是彈5横朋。不信你試試仑乌。為什么呢∏俣В看下面分析晰甚。

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

  }

  // i = 5對吧

lis[0].onclick = function(){

alert(i);

};

lis[1].onclick = function(){

alert(i);

};

lis[2].onclick = function(){

alert(i);

};

lis[3].onclick = function(){

alert(i);

};

lis[4].onclick = function(){

alert(i);

};

為什么會這樣呢,因為你for循環(huán)只是給li綁定事件决帖,但是里面的函數(shù)代碼并不會執(zhí)行啊厕九,這個執(zhí)行是在你點擊的時候才執(zhí)行的好吧?但是此時的i已經(jīng)是5了地回,所以所有的都打印出5來了扁远。

如果想解決這個問題我們可以使用閉包,閉包的特點不只是讓函數(shù)外部訪問函數(shù)內(nèi)部變量這么簡單刻像,還有一個大的特點就是通過閉包我們可以讓函數(shù)中的變量持久保持畅买。來看。

function fn(){

var num = 0;

return function(){

num+=1;

       alert(num);   

     };  

  }

  var f = fn();

  f(); //1

  f(); //2
 如果你是初學(xué)者可能沒覺得這有什么绎速。OK皮获,讓你看個東西。

function fn(){

    var num = 5;

    num+=1;

    alert(num);

 }  

fn(); //6

fn(); //6
 為什么呢纹冤?因為函數(shù)一旦調(diào)用里面的內(nèi)容就會被銷毀洒宝,下一次調(diào)用又是一個新的函數(shù),和上一個調(diào)用的不相關(guān)了萌京,不過有個特殊的情況雁歌,看這:

function fn(){

var num = 0;

return function(){

num+=1;

       alert(num);   

     };  

  }

  var f = fn();

  f(); //1

  f(); //2
這段代碼很簡單,不要被它欺騙了知残,我們首頁定義了一個fn函數(shù)靠瞎,里面有個num默認(rèn)為0,接著返回了一個匿名函數(shù)(也就是沒有名字的函數(shù))。我們在外部用f接收這個返回的函數(shù)乏盐。這個匿名函數(shù)干的事情就是把num加1佳窑,還有我們用來調(diào)試的alert。

這里之所以執(zhí)行玩這個函數(shù)num沒有被銷毀是因為那個匿名函數(shù)的問題父能,因為這個匿名函數(shù)用到了這個num神凑,所以沒有被銷毀,一直保持在內(nèi)存中何吝,因此我們f()時num可以一直加溉委。

這里你可以看不懂了,之所以有這種感覺是因為js回收機制你不懂爱榕,強烈建議你看我之前的再次講解js中的回收機制是怎么一回事瓣喊。這篇文章。

關(guān)于閉包的知識就到這里了黔酥,如果你想看關(guān)于閉包的案例可以看這篇:從閉包案例中學(xué)習(xí)閉包的作用藻三,會不會由你。

而外:關(guān)于在for循環(huán)中綁定事件打印變量i是最后一次絮爷。

而外說一句:這里并不是說return就是閉包趴酣,這里只是強調(diào)return的重要性梨树,如果你還是一個新手建議你多看一些初級文章坑夯,在來看這篇文章,希望你會有新收獲抡四。寫這篇文章一開始我也說了它的目的是回顧一下當(dāng)初我沒有理解的地方柜蜈,當(dāng)初已經(jīng)理解的這篇文章并沒有過多的去講。

作用域竟然上面已經(jīng)講完了~~~

大前端 369451410歡迎你的加入指巡。

那就說一下this:

我們經(jīng)常用this淑履,但是也許你還不清楚它是什么吧?

lis[i].onclick=function(){this.style.border="1px solid #ccc";} ;

 此時的this表示lis[?]它的引用藻雪。

 這里的i不是i實際上是一個準(zhǔn)確的數(shù)字:如lis[2].onclick = function(){this.style.border="1px solid #ccc";}; this = lis[2] 秘噪;
 簡單來說**this它始終引用一個對象。**

lis[2]它也一個對象勉耀,是一個HTMLElement對象指煎。

   其實不管什么情況下它都會有對象的,這個你不用操心便斥,看

function fn(){

this.name = "追夢子";

      };    

      fn();

      alert(this.name);//追夢子

      //當(dāng)然也可以這樣

alert(name);

       雖然這段代碼中看似沒有對象至壤,但大錯特錯,因為瀏覽器環(huán)境中默認(rèn)就有一個window對象枢纠,因此你在函數(shù)中直接用this.name實際上這個this就表示window像街。

var json = {

name:'yyy',

fn:function(){alert(this.name)}

};

json.fn(); // yyy;

fn屬于json,所以this實際上就是json。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末镰绎,一起剝皮案震驚了整個濱河市脓斩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌畴栖,老刑警劉巖俭厚,帶你破解...
    沈念sama閱讀 222,946評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異驶臊,居然都是意外死亡挪挤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,336評論 3 399
  • 文/潘曉璐 我一進店門关翎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來扛门,“玉大人,你說我怎么就攤上這事纵寝÷壅” “怎么了?”我有些...
    開封第一講書人閱讀 169,716評論 0 364
  • 文/不壞的土叔 我叫張陵爽茴,是天一觀的道長葬凳。 經(jīng)常有香客問我,道長室奏,這世上最難降的妖魔是什么火焰? 我笑而不...
    開封第一講書人閱讀 60,222評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮胧沫,結(jié)果婚禮上昌简,老公的妹妹穿的比我還像新娘。我一直安慰自己绒怨,他們只是感情好纯赎,可當(dāng)我...
    茶點故事閱讀 69,223評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著南蹂,像睡著了一般犬金。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上六剥,一...
    開封第一講書人閱讀 52,807評論 1 314
  • 那天晚顷,我揣著相機與錄音,去河邊找鬼仗考。 笑死音同,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的秃嗜。 我是一名探鬼主播权均,決...
    沈念sama閱讀 41,235評論 3 424
  • 文/蒼蘭香墨 我猛地睜開眼顿膨,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了叽赊?” 一聲冷哼從身側(cè)響起恋沃,我...
    開封第一講書人閱讀 40,189評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎必指,沒想到半個月后囊咏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,712評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡塔橡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,775評論 3 343
  • 正文 我和宋清朗相戀三年梅割,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片葛家。...
    茶點故事閱讀 40,926評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡户辞,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出癞谒,到底是詐尸還是另有隱情底燎,我是刑警寧澤,帶...
    沈念sama閱讀 36,580評論 5 351
  • 正文 年R本政府宣布弹砚,位于F島的核電站双仍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏桌吃。R本人自食惡果不足惜朱沃,卻給世界環(huán)境...
    茶點故事閱讀 42,259評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望读存。 院中可真熱鬧为流,春花似錦呕屎、人聲如沸让簿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,750評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽尔当。三九已至,卻和暖如春蹂安,著一層夾襖步出監(jiān)牢的瞬間椭迎,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,867評論 1 274
  • 我被黑心中介騙來泰國打工田盈, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留畜号,地道東北人。 一個月前我還...
    沈念sama閱讀 49,368評論 3 379
  • 正文 我出身青樓允瞧,卻偏偏與公主長得像简软,于是被迫代替她去往敵國和親蛮拔。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,930評論 2 361

推薦閱讀更多精彩內(nèi)容