Heim >Web-Frontend >js-Tutorial >Analyse einer JS-Front-End-Interviewfrage_Javascript-Fähigkeiten
Frage
Code A
function fun(n,o){ console.log(o); return { fun:function(m){//[2] return fun(m,n);//[1] } } } 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);
Suchen Sie die Programmausgabe
Dies ist eine Abschlusstestfrage
Konvertieren in äquivalenten Code
Das fun-Attribut des von return zurückgegebenen Objekts entspricht einem neu erstellten Funktionsobjekt, das den Zugriff auf die Variable n der äußeren Funktion und den äußeren Funktionsspaß ermöglicht Kombinieren Sie die Spaßfunktion mit Das Spaßattribut ist verwirrt, wir ändern den obigen Code wie folgt:
Code B
function _fun_(n,o){ console.log(o); return { fun:function(m){ return _fun_(m,n); } } } var a=_fun_(0);//undefined a.fun(1);//0 a.fun(2);//0 a.fun(3);//0 var b=_fun_(0).fun(1).fun(2).fun(3); //undefined,0,1,2 var c=fun(0).fun(1);//undefined,0, c.fun(2);//1 c.fun(3); //1
Dann fragten einige Schüler, warum es so geändert werden kann. Wie können Sie sicher sein, dass der Spaß bei [1] nicht der Spaß bei [2] ist, bei dem sich der Code befindet? zeigt auf ein Funktionsobjekt
Hier sprechen wir über den lexikalischen Bereich von JS. Der JS-Variablenbereich existiert im Funktionskörper, dh im Funktionskörper, und der Gültigkeitsbereich der Variablen wird bei der Deklaration der Funktionsdefinition und nicht beim Ausführen der Funktion bestimmt.
Der folgende Code
var name="global"; function foo(){ console.log(name); } function fooOuter1(){ var name="local"; foo(); } fooOuter1();//输出global 而不是local,并且和闭包没有任何关系 function fooOuter2(){ var name="local"; function foo(){ console.log(name); } foo(); } fooOuter2();//输出local 而不是global,在函数声明是name变量作用域就在其外层函数中,嗯嗯就是闭包~<br />
Abschlussbereich erstellen
Nach der lexikalischen Analyse bestimmt JS einen Abschluss, bei dem es sich um den Abschluss der anonymen Funktion handelt, die dem Spaßattribut des zurückgegebenen Objekts entspricht – der internen Funktionsvariablen n, die auf _func_ in der globalen Umgebung zugreift, und ihrer äußeren Funktion; > Jedes Mal, wenn _func_ ausgeführt wird, werden die Bereichsinformationen der Variablen im Abschluss an die Funktionsausführungsumgebung übergeben, um sie beim Abrufen des Variablenwerts zu verwenden, wenn die Funktion ausgeführt wird
Ausführungsausgabe
var a=_fun_(0);//undefined a.fun(1);//0 a.fun(2);//0 a.fun(3);//0_fun_ Funktion wird ausgeführt, da der zweite Parameter undefiniert ist, ist die Ausgabe undefiniert. Geben Sie dann ein Objekt mit dem Attribut „fun“ zurück, das auf ein Funktionsobjekt zeigt – mit einem Abschluss, der auf _fun_ und die Variable n_
zurück
Die Ausgabe ist also 0, a.fun(2), a.fun(3) und a.fun(1)
var b=_fun_(0).fun(1).fun(2).fun(3);
Äquivalenter Code:
var b=_fun_(0);
var b1=b.fun(1);
var b2=b1.fun(2);//[3]
var b3=b2.fun(3);//[4]
Die ersten beiden Sätze sind dieselben wie die obige Ausgabe undefiniert,0. Wenn [3] aufgerufen wird, gibt es einen Abschluss im b1-Objekt, der auf die Funktion _fun_ und die äußere Funktionsvariable n=1 verweist , also Der von der anonymen Funktion ausgeführte Funktionsaufruf ist _fun_(2,1), das Ausgabeergebnis ist 1 und ein neues Objekt wird zurückgegeben.
Wenn [4] ausgeführt wird, hat das b2-Objekt auch einen Abschluss, der sich auf die Funktion _fun_ und die äußere Funktionsvariable n=2 bezieht. Wenn _fun_(3,2) ausgeführt wird, ist das Ausgabeergebnis 2
var c=fun(0).fun(1);//undefined,0, c.fun(2);//1 c.fun(3); //1Wenn Sie die vorherige Codeausführungserklärung und die obige Codeausführungsausgabe verstehen, wird es Ihnen hoffentlich gefallen.