成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

簡單說 一道JS閉包面試題

Lin_YT / 1114人閱讀

摘要:說明最近看到這樣一段代碼問三行的輸出分別是什么覺得有點意思,和大家一起來聊聊。說到這里,這道題基本上可以解決了,希望大家能聽明白我上面說的話,下面的就簡單了。

說明

最近看到這樣一段代碼

 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);
 //問:三行a,b,c的輸出分別是什么?

覺得有點意思,和大家一起來聊聊。
我相信如果你不是非常理解JavaScript中的閉包,一定是不想看這段代碼的。

解釋

好的,我們暫時先不去想這段代碼,先看點簡單的

function fun0(){
    var a=1;
    console.log(a);
}
function fun1(){
    console.log(a);
}
fun0();    //1
fun1();    //報錯 a is not defined

這段代碼,我相信大家應(yīng)該知道最后為什么結(jié)果會是 1 和 報錯 的,在函數(shù)內(nèi)聲明的變量只在函數(shù)體內(nèi)定義,它們是局部變量,作用域是局部的,所以 函數(shù) fun1 調(diào)用后,找不到a,就報錯了,JavaScript采用詞法作用域,函數(shù)的執(zhí)行依賴于變量作用域,這個作用域是在函數(shù)定義時決定的,所以我們只要改改上面函數(shù) fun1的位置,它就不會報錯了。

function fun0(){
    var a=1;
    console.log(a);

    //把fun1放在fun0中,就不報錯了
    function fun1(){
        console.log(a);
    }
    fun1();   //1
}
fun0();   //1

代碼改成這樣,只是把fun1 放在 fun0 中就不報錯了,函數(shù)調(diào)用后都輸出1

好了,我們來看最開始提到的代碼,先簡化一下

function fun(n,o){
    return {
    }
}

我們先看這段代碼,fun 調(diào)用后會怎么樣?
很明顯會返回一個空對象,記住,fun調(diào)用后會返回對象,這點很重要。

 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è)置為undefined值。
console.log(o); 輸出undefined
var a = fun(0); 那a是值是什么,是fun(0),返回的那個對象

{
    fun:function(m){
        return fun(m,0);
    }
}

這個對象,有一個fun的方法,方法返回的結(jié)果就是最外面 fun 調(diào)用的結(jié)果。

var a=fun(0),傳入一個參數(shù)0,那就是說,函數(shù)fun中參數(shù) n 的值是0了,而返回的那個對象中,需要一個參數(shù)n,而這個對象的作用域中沒有n,它就繼續(xù)沿著作用域向上一級的作用域中尋找n,最后在函數(shù)fun中找到了n,n的值是0,這段話是本文的重點, 明白這段,那問題就容易解決了。

說到這里,這道題基本上可以解決了,希望大家能聽明白我上面說的話,下面的就簡單了。我們一步一步看。

現(xiàn)在我們知道 a 是

{
    fun:function(m){
        return fun(m,0);
    }
}

這樣的一個對象
a.fun(1); 會怎么樣?看代碼

{
    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,并返回一個對象,這個對象有一個fun的方法,這個方法調(diào)用后,會返回外層fun函數(shù)調(diào)用的結(jié)果,并且外層函數(shù)的第二個參數(shù)是 n 的值,也就是1  

a.fun(2); 會怎么樣?看代碼

{
    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,并返回一個對象,這個對象有一個fun的方法,這個方法調(diào)用后,會返回外層fun函數(shù)調(diào)用的結(jié)果,并且外層函數(shù)的第二個參數(shù)是 n 的值,也就是2  

a.fun(3); 就不說了,一樣的。

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

我們繼續(xù)說b,b和a的不同在于, var a = fun(0); 之后一直用的是a這個對象,是同一個對象,而b每次用的都是上次返回的對象。
如果改成這樣

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);

把返回的對象,重新賦值給a,這樣兩行的結(jié)果就是一樣的了。
var c = fun(0).fun(1); c.fun(2); c.fun(3);
c 與他們的不同,只是var c = fun(0).fun(1); 之后用的是同一個對象罷了。

總結(jié)

說下結(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

最開始的代碼來自這里
http://www.cnblogs.com/xxcang...

這篇文章只是針對這道題講了講,沒有非常著重的去講閉包這個概念,所以如果朋友們,對閉包詳細(xì)的概念還不是很理解,要趕緊學(xué)習(xí)了。
順便推薦幾篇講解閉包的文章

學(xué)習(xí)Javascript閉包(Closure)
Javascript閉包——懂不懂由你,反正我是懂了
JS閉包可被利用的常見場景

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/51480.html

相關(guān)文章

  • 簡單 一道JS閉包面試

    摘要:說明最近看到這樣一段代碼問三行的輸出分別是什么覺得有點意思,和大家一起來聊聊。說到這里,這道題基本上可以解決了,希望大家能聽明白我上面說的話,下面的就簡單了。 說明 最近看到這樣一段代碼 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...

    mushang 評論0 收藏0
  • 簡單 一道JS閉包面試

    摘要:說明最近看到這樣一段代碼問三行的輸出分別是什么覺得有點意思,和大家一起來聊聊。說到這里,這道題基本上可以解決了,希望大家能聽明白我上面說的話,下面的就簡單了。 說明 最近看到這樣一段代碼 function fun(n,o){ console.log(o); return { fun:function(m){ return fun...

    banana_pi 評論0 收藏0
  • 一道js閉包面試的學(xué)習(xí)

    摘要:然后最外層這個函數(shù)會返回一個新對象,對象里面有一個屬性,名為,而這個屬性的值是一個匿名函數(shù),它會返回。 最近看到一條有意思的閉包面試題,但是看到原文的解析,我自己覺得有點迷糊,所以自己重新做一下這條題目。 閉包面試題原題 function fun(n, o) { // ① console.log(o); return { // ② fun: function(m) ...

    plus2047 評論0 收藏0
  • 一道JS前端閉包面試解析

    摘要:當(dāng)執(zhí)行時,對象也有一個閉包,引用了函數(shù)及外層函數(shù)變量,執(zhí)行輸出結(jié)果為能看懂前面的代碼執(zhí)行解釋,理解上面的代碼執(zhí)行輸出就不會有問題了 問題 代碼A function fun(n,o){ console.log(o); return { fun:function(m){//[2] return fun(m,n);//[1] ...

    malakashi 評論0 收藏0

發(fā)表評論

0條評論

Lin_YT

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<