摘要:說(shuō)明最近看到這樣一段代碼問(wèn)三行的輸出分別是什么覺(jué)得有點(diǎn)意思,和大家一起來(lái)聊聊。說(shuō)到這里,這道題基本上可以解決了,希望大家能聽(tīng)明白我上面說(shuō)的話,下面的就簡(jiǎn)單了。
說(shuō)明
最近看到這樣一段代碼
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); //問(wèn):三行a,b,c的輸出分別是什么?
覺(jué)得有點(diǎn)意思,和大家一起來(lái)聊聊。
我相信如果你不是非常理解JavaScript中的閉包,一定是不想看這段代碼的。
好的,我們暫時(shí)先不去想這段代碼,先看點(diǎn)簡(jiǎn)單的
function fun0(){ var a=1; console.log(a); } function fun1(){ console.log(a); } fun0(); //1 fun1(); //報(bào)錯(cuò) a is not defined
這段代碼,我相信大家應(yīng)該知道最后為什么結(jié)果會(huì)是 1 和 報(bào)錯(cuò) 的,在函數(shù)內(nèi)聲明的變量只在函數(shù)體內(nèi)定義,它們是局部變量,作用域是局部的,所以 函數(shù) fun1 調(diào)用后,找不到a,就報(bào)錯(cuò)了,JavaScript采用詞法作用域,函數(shù)的執(zhí)行依賴于變量作用域,這個(gè)作用域是在函數(shù)定義時(shí)決定的,所以我們只要改改上面函數(shù) fun1的位置,它就不會(huì)報(bào)錯(cuò)了。
function fun0(){ var a=1; console.log(a); //把fun1放在fun0中,就不報(bào)錯(cuò)了 function fun1(){ console.log(a); } fun1(); //1 } fun0(); //1
代碼改成這樣,只是把fun1 放在 fun0 中就不報(bào)錯(cuò)了,函數(shù)調(diào)用后都輸出1
好了,我們來(lái)看最開(kāi)始提到的代碼,先簡(jiǎn)化一下
function fun(n,o){ return { } }
我們先看這段代碼,fun 調(diào)用后會(huì)怎么樣?
很明顯會(huì)返回一個(gè)空對(duì)象,記住,fun調(diào)用后會(huì)返回對(duì)象,這點(diǎn)很重要。
function fun(n,o){ console.log(o); return { fun:function(m){ return fun(m,n); } }; } var a = fun(0);
這里提一句,當(dāng)調(diào)用函數(shù)的時(shí)候傳入的實(shí)參比函數(shù)聲明時(shí)指定的形參個(gè)數(shù)要少,剩下的形參都將設(shè)置為undefined值。
console.log(o); 輸出undefined
var a = fun(0); 那a是值是什么,是fun(0),返回的那個(gè)對(duì)象
{ fun:function(m){ return fun(m,0); } }
這個(gè)對(duì)象,有一個(gè)fun的方法,方法返回的結(jié)果就是最外面 fun 調(diào)用的結(jié)果。
var a=fun(0),傳入一個(gè)參數(shù)0,那就是說(shuō),函數(shù)fun中參數(shù) n 的值是0了,而返回的那個(gè)對(duì)象中,需要一個(gè)參數(shù)n,而這個(gè)對(duì)象的作用域中沒(méi)有n,它就繼續(xù)沿著作用域向上一級(jí)的作用域中尋找n,最后在函數(shù)fun中找到了n,n的值是0,這段話是本文的重點(diǎn), 明白這段,那問(wèn)題就容易解決了。
說(shuō)到這里,這道題基本上可以解決了,希望大家能聽(tīng)明白我上面說(shuō)的話,下面的就簡(jiǎn)單了。我們一步一步看。
現(xiàn)在我們知道 a 是
{ fun:function(m){ return fun(m,0); } }
這樣的一個(gè)對(duì)象
a.fun(1); 會(huì)怎么樣?看代碼
{ fun:function(1){ return fun(1,0); } }
a.fun(1); 返回的結(jié)果,就是 fun(1,0),返回的結(jié)果
function fun(n,o){ //n的值為1,o的值為0 console.log(o); return { fun:function(m){ return fun(m,n);//n的值為1 } }; } fun(1,0); //輸出0,并返回一個(gè)對(duì)象,這個(gè)對(duì)象有一個(gè)fun的方法,這個(gè)方法調(diào)用后,會(huì)返回外層fun函數(shù)調(diào)用的結(jié)果,并且外層函數(shù)的第二個(gè)參數(shù)是 n 的值,也就是1
a.fun(2); 會(huì)怎么樣?看代碼
{ fun:function(2){ return fun(2,0); } }
a.fun(2); 返回的結(jié)果,就是 fun(2,0),返回的結(jié)果
function fun(n,o){ //n的值為2,o的值為0 console.log(o); return { fun:function(m){ return fun(m,n); //n的值為2 } }; } fun(2,0); //輸出0,并返回一個(gè)對(duì)象,這個(gè)對(duì)象有一個(gè)fun的方法,這個(gè)方法調(diào)用后,會(huì)返回外層fun函數(shù)調(diào)用的結(jié)果,并且外層函數(shù)的第二個(gè)參數(shù)是 n 的值,也就是2
a.fun(3); 就不說(shuō)了,一樣的。
var a = fun(0); a.fun(1); a.fun(2); a.fun(3); var b = fun(0).fun(1).fun(2).fun(3);
我們繼續(xù)說(shuō)b,b和a的不同在于, var a = fun(0); 之后一直用的是a這個(gè)對(duì)象,是同一個(gè)對(duì)象,而b每次用的都是上次返回的對(duì)象。
如果改成這樣
var a = fun(0); a=a.fun(1); a=a.fun(2); a=a.fun(3); var b = fun(0).fun(1).fun(2).fun(3);
把返回的對(duì)象,重新賦值給a,這樣兩行的結(jié)果就是一樣的了。
var c = fun(0).fun(1); c.fun(2); c.fun(3);
c 與他們的不同,只是var c = fun(0).fun(1); 之后用的是同一個(gè)對(duì)象罷了。
說(shuō)下結(jié)果
var a = fun(0); a.fun(1); a.fun(2); a.fun(3); //undefined 0 0 0 var b = fun(0).fun(1).fun(2).fun(3); //undefined 0 1 2 var c = fun(0).fun(1); c.fun(2); c.fun(3); //undefined 0 1 1
最開(kāi)始的代碼來(lái)自這里
http://www.cnblogs.com/xxcang...
這篇文章只是針對(duì)這道題講了講,沒(méi)有非常著重的去講閉包這個(gè)概念,所以如果朋友們,對(duì)閉包詳細(xì)的概念還不是很理解,要趕緊學(xué)習(xí)了。
順便推薦幾篇講解閉包的文章
學(xué)習(xí)Javascript閉包(Closure)
Javascript閉包——懂不懂由你,反正我是懂了
JS閉包可被利用的常見(jiàn)場(chǎng)景
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/51480.html
摘要:說(shuō)明最近看到這樣一段代碼問(wèn)三行的輸出分別是什么覺(jué)得有點(diǎn)意思,和大家一起來(lái)聊聊。說(shuō)到這里,這道題基本上可以解決了,希望大家能聽(tīng)明白我上面說(shuō)的話,下面的就簡(jiǎn)單了。 說(shuō)明 最近看到這樣一段代碼 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...
摘要:說(shuō)明最近看到這樣一段代碼問(wèn)三行的輸出分別是什么覺(jué)得有點(diǎn)意思,和大家一起來(lái)聊聊。說(shuō)到這里,這道題基本上可以解決了,希望大家能聽(tīng)明白我上面說(shuō)的話,下面的就簡(jiǎn)單了。 說(shuō)明 最近看到這樣一段代碼 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...
摘要:然后最外層這個(gè)函數(shù)會(huì)返回一個(gè)新對(duì)象,對(duì)象里面有一個(gè)屬性,名為,而這個(gè)屬性的值是一個(gè)匿名函數(shù),它會(huì)返回。 最近看到一條有意思的閉包面試題,但是看到原文的解析,我自己覺(jué)得有點(diǎn)迷糊,所以自己重新做一下這條題目。 閉包面試題原題 function fun(n, o) { // ① console.log(o); return { // ② fun: function(m) ...
摘要:當(dāng)執(zhí)行時(shí),對(duì)象也有一個(gè)閉包,引用了函數(shù)及外層函數(shù)變量,執(zhí)行輸出結(jié)果為能看懂前面的代碼執(zhí)行解釋,理解上面的代碼執(zhí)行輸出就不會(huì)有問(wèn)題了 問(wèn)題 代碼A function fun(n,o){ console.log(o); return { fun:function(m){//[2] return fun(m,n);//[1] ...
閱讀 1371·2023-04-25 16:45
閱讀 1917·2021-11-17 09:33
閱讀 2306·2021-09-27 14:04
閱讀 915·2019-08-30 15:44
閱讀 2633·2019-08-30 14:24
閱讀 3411·2019-08-30 13:59
閱讀 1691·2019-08-29 17:00
閱讀 887·2019-08-29 15:33