suchen
HeimWeb-Frontendjs-TutorialJS-Abschlussinterviewfragen, die Sie durch unfallbedingte Javascript-Kenntnisse falsch machen können

Interviewfragen haben sich aus der Arbeit entwickelt

Das ist eine Frage, die mir bei der Arbeit begegnet ist. Sie erschien mir sehr interessant, also habe ich sie zu einer Frage für Vorstellungsgespräche gemacht. Ich stellte fest, dass fast niemand alle Fragen richtig beantworten und die Gründe nennen konnte, also habe ich sie aufgegriffen und mit ihr gesprochen darüber.

Schauen Sie sich zuerst den Fragecode an:

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);//undefined,?,?,?
var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,?,?,?
//问:三行a,b,c的输出分别是什么?


Dies ist ein sehr typisches JS-Schließungsproblem. Darin sind drei Ebenen mit Spaßfunktionen verschachtelt. Es ist besonders wichtig herauszufinden, um welche Spaßfunktion es sich bei der jeweiligen Ebene handelt.

Sie können die Ergebnisse, die Sie denken, zunächst auf Papier oder an anderen Orten aufschreiben und dann erweitern, um zu sehen, was die richtige Antwort ist?

Antwort

//a: undefined,0,0,0
//b: undefined,0,1,2
//c: undefined,0,1,1

Hast du alles richtig gemacht? Wenn Sie alles richtig beantwortet haben, herzlichen Glückwunsch. Es gibt fast nichts, was Sie beim js-Abschlussproblem überraschen kann. Wenn es keine Antwort gibt, fahren Sie mit der Analyse fort.

Es gibt mehrere Funktionen in JS

Zuvor müssen Sie zunächst verstehen, dass Funktionen in JS in zwei Typen unterteilt werden können: benannte Funktionen (benannte Funktionen) und anonyme Funktionen.

Die Methode zur Unterscheidung dieser beiden Funktionen ist sehr einfach. Sie können dies anhand der Ausgabe von fn.name beurteilen. Die Funktion mit einem Namen ist eine benannte Funktion und die Funktion ohne Namen ist eine anonyme Funktion.

Hinweis: Der Name der benannten Funktion kann in niedrigeren Versionen des IE nicht abgerufen werden und wird als undefiniert zurückgegeben. Es wird empfohlen, ihn in Firefox oder Google Chrome zu testen.

Oder verwenden Sie die IE-kompatible Methode zum Abrufen des Funktionsnamens, um den Funktionsnamen abzurufen:

/**
  * 获取指定函数的函数名称(用于兼容IE)
  * @param {Function} fun 任意函数
  */
function getFunctionName(fun) {
  if (fun.name !== undefined)
    return fun.name;
  var ret = fun.toString();
  ret = ret.substr('function '.length);
  ret = ret.substr(0, ret.indexOf('('));
  return ret;
}

Verwenden Sie die obige Funktion, um zu testen, ob es sich um eine anonyme Funktion handelt:

Sie können wissen, dass die Variable fn1 eine benannte Funktion und fn2 eine anonyme Funktion ist

Mehrere Möglichkeiten, Funktionen zu erstellen

Nachdem Sie über die Funktionstypen gesprochen haben, müssen Sie auch verstehen, dass es mehrere Möglichkeiten gibt, Funktionen in JS zu erstellen.

1. Funktion deklarieren

Die gebräuchlichste und standardmäßigste Methode zum Deklarieren einer Funktion, einschließlich Funktionsname und Funktionskörper.

Funktion fn1(){}

2. Anonymen Funktionsausdruck erstellen

Erstellen Sie eine Variable, deren Inhalt eine Funktion ist

var fn1=function (){}
Beachten Sie, dass die mit dieser Methode erstellte Funktion eine anonyme Funktion ist, das heißt, es gibt keinen Funktionsnamen

var fn1=function (){};
getFunctionName(fn1).length;//0 

3. Erstellen Sie einen benannten Funktionsausdruck

Erstellen Sie eine Variable, die eine Funktion mit einem Namen enthält

var fn1=function xxcanghai(){};
Hinweis: Der Funktionsname eines benannten Funktionsausdrucks kann nur innerhalb der erstellten Funktion verwendet werden

Das heißt, die mit dieser Methode erstellte Funktion kann nur fn1 und nicht den Funktionsnamen von xxcanghai in der äußeren Ebene der Funktion verwenden. Die Benennung von xxcanghai kann nur innerhalb der erstellten Funktion

verwendet werden

Test:

var fn1=function xxcanghai(){
  console.log("in:fn1<",typeof fn1,">xxcanghai:<",typeof xxcanghai,">");
};
console.log("out:fn1<",typeof fn1,">xxcanghai:<",typeof xxcanghai,">");
fn1();
//out:fn1< function >xxcanghai:< undefined >
//in:fn1< function >xxcanghai:< function >

Sie können sehen, dass der Funktionsname von xxcanghai nicht außerhalb der Funktion (out) verwendet werden kann und undefiniert ist.

Hinweis: Das Definieren einer Funktion innerhalb eines Objekts wie var o={ fn : function (){…} } ist auch ein Funktionsausdruck

4. Funktionskonstruktor

Sie können eine Funktionszeichenfolge an den Funktionskonstruktor übergeben und eine Funktion zurückgeben, die diesen Zeichenfolgenbefehl enthält. Diese Methode erstellt eine anonyme Funktion.

5. Selbstausführende Funktion

(function(){alert(1);})();
(function fn1(){alert(1);})();

Selbstausführende Funktionen gehören zu den oben genannten „Funktionsausdrücken“ und die Regeln sind die gleichen

6. Andere Möglichkeiten, Funktionen zu erstellen

Natürlich gibt es auch andere Möglichkeiten, Funktionen zu erstellen oder auszuführen. Ich werde zum Beispiel nicht auf die Verwendung von eval, setInterval eingehen. Da es sich hierbei nicht um Standardmethoden handelt, werde ich hier nicht zu sehr darauf eingehen

Welcher Zusammenhang besteht zwischen den drei Spaßfunktionen?

Nachdem Sie über Funktionstypen und Methoden zum Erstellen von Funktionen gesprochen haben, können Sie zum Thema zurückkehren und sich diese Interviewfrage ansehen.

Dieser Code enthält drei unterhaltsame Funktionen. Der erste Schritt besteht darin, die Beziehung zwischen diesen drei unterhaltsamen Funktionen herauszufinden und herauszufinden, welche Funktion mit welcher Funktion identisch ist.

function fun(n,o) {
 console.log(o)
 return {
  fun:function(m){
   //...
  }
 };
} 

先看第一个fun函数,属于标准具名函数声明,是新创建的函数,他的返回值是一个对象字面量表达式,属于一个新的object。

这个新的对象内部包含一个也叫fun的属性,通过上述介绍可得知,属于匿名函数表达式,即fun这个属性中存放的是一个新创建匿名函数表达式。

注意:所有声明的匿名函数都是一个新函数。

所以第一个fun函数与第二个fun函数不相同,均为新创建的函数。

函数作用域链的问题

再说第三个fun函数之前需要先说下,在函数表达式内部能不能访问存放当前函数的变量。

测试1:对象内部的函数表达式:

var o={
 fn:function (){
  console.log(fn);
 }
};
o.fn();//ERROR报错

测试2:非对象内部的函数表达式:

var fn=function (){
 console.log(fn);
};
fn();//function (){console.log(fn);};正确


结论:使用var或是非对象内部的函数表达式内,可以访问到存放当前函数的变量;在对象内部的不能访问到。

原因也非常简单,因为函数作用域链的问题,采用var的是在外部创建了一个fn变量,函数内部当然可以在内部寻找不到fn后向上册作用域查找fn,而在创建对象内部时,因为没有在函数作用域内创建fn,所以无法访问。

 

所以综上所述,可以得知,最内层的return出去的fun函数不是第二层fun函数,是最外层的fun函数。

所以,三个fun函数的关系也理清楚了,第一个等于第三个,他们都不等于第二个。

到底在调用哪个函数?

再看下原题,现在知道了程序中有两个fun函数(第一个和第三个相同),遂接下来的问题是搞清楚,运行时他执行的是哪个fun函数?

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);//undefined,&#63;,&#63;,&#63;
var b = fun(0).fun(1).fun(2).fun(3);//undefined,&#63;,&#63;,&#63;
var c = fun(0).fun(1); c.fun(2); c.fun(3);//undefined,&#63;,&#63;,&#63;
//问:三行a,b,c的输出分别是什么? 

1. Die erste Zeile a

var a = fun(0); a.fun(1); a.fun(3);
Es ist bekannt, dass der erste Spaß (0) die Spaßfunktion der ersten Ebene aufruft. Der zweite Fun(1) ist die Fun-Funktion, die den Rückgabewert des vorherigen Fun aufruft, also:

Die letzten Funktionen fun(1), fun(2), fun(3) rufen alle die Fun-Funktion der zweiten Ebene auf.

Dann:

Wenn fun(0) zum ersten Mal aufgerufen wird, ist o undefiniert;

Wenn fun(1) zum zweiten Mal aufgerufen wird, ist m 1. Zu diesem Zeitpunkt schließt fun n der äußeren Funktion, d. h. n = 0 für den ersten Aufruf, d. h. m = 1, n =0, und in der ersten Ebene wird die Fun-Funktion fun(1,0) intern aufgerufen; also ist o

Wenn fun(2) zum dritten Mal aufgerufen wird, ist m 2, aber a.fun wird immer noch aufgerufen, sodass n aus dem ersten Aufruf immer noch geschlossen ist, sodass die erste Ebene von fun(2,0) aufgerufen wird intern. ;Also ist o 0

Das Gleiche wie beim vierten Mal;

Das heißt: Die endgültige Antwort ist undefiniert,0,0,0

2. Die zweite Zeile b

var b = fun(0).fun(1).fun(2).fun(3);//undefiniert,?,?,?
Beginnen wir mit fun(0) Es muss die Fun-Funktion der ersten Ebene sein und ihr Rückgabewert ist ein Objekt, also ruft die Fun-Funktion der zweiten Ebene auf Im Folgenden werden auch die Fun-Funktionen der zweiten Ebene genannt.

Dann:

Wenn die erste Ebene fun(0) zum ersten Mal aufgerufen wird, ist o undefiniert;

Wenn .fun(1) zum zweiten Mal aufgerufen wird, ist m 1. Zu diesem Zeitpunkt schließt fun n der äußeren Funktion, d. h. n = 0 für den ersten Aufruf, d. h. m = 1, n=0, und rufen Sie intern die Fun-Funktion der ersten Ebene auf, also ist o

Wenn .fun(2) zum dritten Mal aufgerufen wird, ist m 2. Zu diesem Zeitpunkt ist die aktuelle Fun-Funktion nicht das Rückgabeobjekt der ersten Ausführung, sondern das Rückgabeobjekt der zweiten Ausführung. Wenn die Spaßfunktion der ersten Ebene zum zweiten Mal ausgeführt wird, (1,0), also n = 1, o = 0, wird das zweite n bei der Rückkehr geschlossen, also wenn die Spaßfunktion der dritten Ebene zum dritten Mal aufgerufen wird Zeit, m =2,n=1, das heißt, die Fun-Funktion fun(2,1) der ersten Ebene wird aufgerufen, also ist o

Wenn .fun(3) zum vierten Mal aufgerufen wird, ist m 3, was das n des dritten Aufrufs schließt. Ebenso ist der letzte Aufruf der Fun-Funktion der ersten Ebene fun(3,2); o ist 2;

Das ist die endgültige Antwort: undefiniert,0,1,2

3. Die dritte Zeile c

var c = fun(0).fun(1); c.fun(2);//undefiniert,?,?,?
Anhand der beiden vorherigen Beispiele können wir Folgendes wissen:
fun(0) führt die Fun-Funktion der ersten Ebene aus, .fun(1) führt die von fun(0) zurückgegebene Fun-Funktion der zweiten Ebene aus, die Anweisung endet hier und c speichert den Rückgabewert von fun(1). , und nicht der Rückgabewert von fun(0), daher ist der Abschluss in c auch der Wert von n, wenn fun(1) zum zweiten Mal ausgeführt wird. c.fun(2) führt die von fun(1) zurückgegebene Fun-Funktion der zweiten Ebene aus, und c.fun(3) führt auch die von fun(1) zurückgegebene Fun-Funktion der zweiten Ebene aus.

Dann:

Wenn die erste Ebene fun(0) zum ersten Mal aufgerufen wird, ist o undefiniert;

Wenn .fun(1) zum zweiten Mal aufgerufen wird, ist m 1. Zu diesem Zeitpunkt schließt fun n der äußeren Funktion, d. h. n = 0 für den ersten Aufruf, d. h. m = 1, n=0, und rufen Sie intern die Fun-Funktion der ersten Ebene auf, also ist o

Wenn .fun(2) zum dritten Mal aufgerufen wird, ist m 2. Zu diesem Zeitpunkt ist der Spaßabschluss für den zweiten Aufruf n=1, also m=2, n=1 und den ersten Die Funktion fun(2,1); ist also 1;

Das Gleiche gilt für .fun(3) zum vierten Mal, aber es ist immer noch der Rückgabewert des zweiten Aufrufs, sodass die Fun-Funktion fun(3,1) der ersten Ebene schließlich aufgerufen wird, sodass o immer noch 1 ist

Das ist die endgültige Antwort: undefiniert,0,1,1

Spätere Wörter Dieser Code wurde ursprünglich beim Umschreiben eines asynchronen Rückrufs in eine synchrone Aufrufkomponente erstellt. Ich habe diese Gefahr entdeckt und ein tieferes Verständnis für JS-Abschlüsse gewonnen.

Es gibt unzählige Artikel im Internet darüber, was Abschlüsse sind, aber um zu verstehen, was Abschlüsse sind, muss man sie erst noch selbst im Code entdecken und verstehen.

Wenn Sie mich fragen, was ein Abschluss ist, denke ich, dass Abschluss im weitesten Sinne bedeutet, dass eine Variable in ihrem eigenen Bereich verwendet wird, der als Abschluss bezeichnet wird.

Haben alle richtig geantwortet? Ich hoffe, dass die Leser durch diesen Artikel ein besseres Verständnis des Schließungsphänomens erlangen können. Wenn Sie andere Erkenntnisse oder Meinungen haben, können Sie diese gerne korrigieren und diskutieren.

Stellungnahme
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Ist JavaScript in C geschrieben? Prüfung der BeweiseIst JavaScript in C geschrieben? Prüfung der BeweiseApr 25, 2025 am 12:15 AM

Ja, der Motorkern von JavaScript ist in C. 1) Die C -Sprache bietet eine effiziente Leistung und die zugrunde liegende Steuerung, die für die Entwicklung der JavaScript -Engine geeignet ist. 2) Die V8-Engine als Beispiel wird sein Kern in C geschrieben, wobei die Effizienz und objektorientierte Eigenschaften von C kombiniert werden.

JavaScripts Rolle: das Web interaktiv und dynamisch machenJavaScripts Rolle: das Web interaktiv und dynamisch machenApr 24, 2025 am 12:12 AM

JavaScript ist das Herzstück moderner Websites, da es die Interaktivität und Dynamik von Webseiten verbessert. 1) Es ermöglicht die Änderung von Inhalten, ohne die Seite zu aktualisieren, 2) Webseiten durch DOMAPI zu manipulieren, 3) Komplexe interaktive Effekte wie Animation und Drag & Drop, 4) die Leistung und Best Practices optimieren, um die Benutzererfahrung zu verbessern.

C und JavaScript: Die Verbindung erklärteC und JavaScript: Die Verbindung erklärteApr 23, 2025 am 12:07 AM

C und JavaScript erreichen die Interoperabilität durch WebAssembly. 1) C -Code wird in das WebAssembly -Modul zusammengestellt und in die JavaScript -Umgebung eingeführt, um die Rechenleistung zu verbessern. 2) In der Spieleentwicklung kümmert sich C über Physik -Engines und Grafikwiedergabe, und JavaScript ist für die Spiellogik und die Benutzeroberfläche verantwortlich.

Von Websites zu Apps: Die verschiedenen Anwendungen von JavaScriptVon Websites zu Apps: Die verschiedenen Anwendungen von JavaScriptApr 22, 2025 am 12:02 AM

JavaScript wird in Websites, mobilen Anwendungen, Desktop-Anwendungen und serverseitigen Programmierungen häufig verwendet. 1) In der Website -Entwicklung betreibt JavaScript DOM zusammen mit HTML und CSS, um dynamische Effekte zu erzielen und Frameworks wie JQuery und React zu unterstützen. 2) Durch reaktnatives und ionisches JavaScript wird ein plattformübergreifendes mobile Anwendungen entwickelt. 3) Mit dem Elektronenframework können JavaScript Desktop -Anwendungen erstellen. 4) Node.js ermöglicht es JavaScript, auf der Serverseite auszuführen und unterstützt hohe gleichzeitige Anforderungen.

Python gegen JavaScript: Anwendungsfälle und Anwendungen verglichenPython gegen JavaScript: Anwendungsfälle und Anwendungen verglichenApr 21, 2025 am 12:01 AM

Python eignet sich besser für Datenwissenschaft und Automatisierung, während JavaScript besser für die Entwicklung von Front-End- und Vollstapel geeignet ist. 1. Python funktioniert in Datenwissenschaft und maschinellem Lernen gut und unter Verwendung von Bibliotheken wie Numpy und Pandas für die Datenverarbeitung und -modellierung. 2. Python ist prägnant und effizient in der Automatisierung und Skripten. 3. JavaScript ist in der Front-End-Entwicklung unverzichtbar und wird verwendet, um dynamische Webseiten und einseitige Anwendungen zu erstellen. 4. JavaScript spielt eine Rolle bei der Back-End-Entwicklung durch Node.js und unterstützt die Entwicklung der Vollstapel.

Die Rolle von C/C bei JavaScript -Dolmetschern und CompilernDie Rolle von C/C bei JavaScript -Dolmetschern und CompilernApr 20, 2025 am 12:01 AM

C und C spielen eine wichtige Rolle in der JavaScript -Engine, die hauptsächlich zur Implementierung von Dolmetschern und JIT -Compilern verwendet wird. 1) C wird verwendet, um JavaScript -Quellcode zu analysieren und einen abstrakten Syntaxbaum zu generieren. 2) C ist für die Generierung und Ausführung von Bytecode verantwortlich. 3) C implementiert den JIT-Compiler, optimiert und kompiliert Hot-Spot-Code zur Laufzeit und verbessert die Ausführungseffizienz von JavaScript erheblich.

JavaScript in Aktion: Beispiele und Projekte in realer WeltJavaScript in Aktion: Beispiele und Projekte in realer WeltApr 19, 2025 am 12:13 AM

Die Anwendung von JavaScript in der realen Welt umfasst Front-End- und Back-End-Entwicklung. 1) Zeigen Sie Front-End-Anwendungen an, indem Sie eine TODO-Listanwendung erstellen, die DOM-Operationen und Ereignisverarbeitung umfasst. 2) Erstellen Sie RESTFUFFUPI über Node.js und express, um Back-End-Anwendungen zu demonstrieren.

JavaScript und das Web: Kernfunktionalität und AnwendungsfälleJavaScript und das Web: Kernfunktionalität und AnwendungsfälleApr 18, 2025 am 12:19 AM

Zu den Hauptanwendungen von JavaScript in der Webentwicklung gehören die Interaktion der Clients, die Formüberprüfung und die asynchrone Kommunikation. 1) Dynamisches Inhaltsaktualisierung und Benutzerinteraktion durch DOM -Operationen; 2) Die Kundenüberprüfung erfolgt vor dem Einreichung von Daten, um die Benutzererfahrung zu verbessern. 3) Die Aktualisierung der Kommunikation mit dem Server wird durch AJAX -Technologie erreicht.

See all articles

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

Video Face Swap

Video Face Swap

Tauschen Sie Gesichter in jedem Video mühelos mit unserem völlig kostenlosen KI-Gesichtstausch-Tool aus!

Heiße Werkzeuge

Dreamweaver Mac

Dreamweaver Mac

Visuelle Webentwicklungstools

VSCode Windows 64-Bit-Download

VSCode Windows 64-Bit-Download

Ein kostenloser und leistungsstarker IDE-Editor von Microsoft

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Sicherer Prüfungsbrowser

Sicherer Prüfungsbrowser

Safe Exam Browser ist eine sichere Browserumgebung für die sichere Teilnahme an Online-Prüfungen. Diese Software verwandelt jeden Computer in einen sicheren Arbeitsplatz. Es kontrolliert den Zugriff auf alle Dienstprogramme und verhindert, dass Schüler nicht autorisierte Ressourcen nutzen.

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools