JavaScript--這道閉包題做起來有意思

0.前言

閉包的定義是什么?我一直覺得狹義上這么形容可能是更加的恰當:父函數包含子函數,并把子函數做為父函數的返回值,來達到保存父函數中局部變量的效果。
在工作的時候,使用閉包的時候還是挺多,不久前在逛博客園的時候,看到了一道關于閉包的題目,感覺確實不錯。

1.原題目

function fun(n, o) {
  console.log(o)  return {
   fun: function(m) {    return fun(m, n);
   }
  };
 }
 var a = fun(0);a.fun(1);a.fun(2);a.fun(3); 
 var b = fun(0).fun(1).fun(2).fun(3);
 var c = fun(0).fun(1);c.fun(2);c.fun(3);
請問 運行結果是什么?

題目的答案,我放在博客的末尾,眾位看官不妨嘗試著自己算一下輸出結果。這道閉包題目,已經是屬于具有一定難度,如果你能夠上來就順利的將這道題搞定。ok,相信閉包這方面,已經很少有能難倒你的了。

2.分析

如果你認真的思考了題目,好的,接下來的內容就是為你寫的。如果你只是看了一眼的話,習慣性看解釋的話,我建議你還是應該嘗試著去做一做。

分析閉包結構:父函數fun,需傳入兩個參數n和o。運行結果返回一個對象。對象內部有一個屬性fun(注意,這里的fun是對象的一個屬性和函數fun不是一碼事),fun屬性的值為一個匿名函數(需要傳入一個參數m),其調用結果則是返回一個fun函數,不過這個函數傳入的參數是m和n;

總結一點,就是fun(n,o)返回對象,fun(n,o).fun(m)的結果=fun(m,n);

3.誰在調用誰?

可能看了上面的分析,你腦袋并沒有清醒多少,沒關系,現在來具體分析一下,到底是誰調用了誰。

  1. 第一行a

    var a = fun(0);a.fun(1);a.fun(2);a.fun(3);

    首先,定義var a = fun(0);這一步也就是相當于調用了函數fun(0,o),n=0,o=?o的值我們沒有給定,所以說這里o=undefined,打印的結果就是undefined;a的執行結果返回一個obj。

    a.fun(1);a.fun(2);a.fun(3);
    這里的a便是上面的對象obj,a.fun(1)即調用了匿名函數,返回fun(m,n),這里m=1,n=0,所以打印結果是0;

    后面同理,所以第一行執行結果是:undefined 0 0 0;

  2. 第二行b

    var b = fun(0).fun(1).fun(2).fun(3);

    可以看到這一行,全部都是通過.連接,調用不同對象的fun屬性,所以跟上面有一點不一樣。

    var b =fun(0).fun(1)執行方式類似于var a = fun(0);a.fun(1);,所以會打印undefined 0。

    繼續向后走,var b =fun(0).fun(1).fun(2),運行到這里,fun(2)fun(1)則不是同一個對象的屬性了,前者是var b =fun(0).fun(1)執行結果所返回的對象的屬性,這樣就會導致m和n的值一直在變化,所以打印的數值也會變化。

    所以,這一行執行結果是:undefined 0 1 2;

  3. 第三行c

    var c = fun(0).fun(1);c.fun(2);c.fun(3);

    第三行,說白就是將前兩行進行了一個結合,前面兩行搞定了,第三行也就搞定了。

    第三行執行結果:undefined 0 1 1;

    所以:結果是
    undefined 0 0 0;
    undefined 0 1 2;
    undefined 0 1 1;

    4.總結

關于閉包,這個概念其實并不難懂,網上對閉包也有各種各樣的解答。真正難的是你如何能后去熟練的運用。在理解閉包的前提下,嘗試著去融入自己的程序,久而久之,我們自然就會孰能生巧了。



文/聽安靜的時光(簡書作者)


上一篇: 一天精通 Chrome 開發

下一篇: 如何合理的規劃前端之路

分享到: 更多
预测大乐透最准的专家 mg游戏平台手机版 三公怎么玩才能赢钱 欢乐二八杠作弊器 时时彩调整20分钟一期 北京pk赛车10官网开奖查询 pk10每期必中万能6码p 十拿九蓝球预测 百人牛牛押注几门稳 重庆时时最新开奖视频 北京单场过关投注方式 高频彩分析app pt电子游戏放水规律 pk10免费辅助软件安卓 3个骰子猜大小规则 斗地主玩法规则