Heim Web-Frontend js-Tutorial Tiefes Verständnis der JavaScript-Bereiche

Tiefes Verständnis der JavaScript-Bereiche

Feb 21, 2017 pm 03:31 PM
javascript 作用域 理解

Tiefes Verständnis der JavaScript-Bereiche

Einführung

JavaScript ist insbesondere eine Full-Stack-Sprache Im Jahr 2016 höre ich oft, dass JavaScript die Welt dominieren wird. Es gibt sogar Gerüchte, dass man 2016 einen Job finden kann, wenn man Vue.js kennt, genauso wie man damals einen Job finden kann, wenn man TableView auf iOS kennt. (tableView basiert ziemlich auf ListView von Android, verwendet aber jetzt im Wesentlichen RecyclerView)

Die beliebten Front-End-Technologien im Jahr 2016 beziehen sich im Wesentlichen auf JavaScript, wie beispielsweise die mobile plattformübergreifende React Native von Facebook und Alibaba Weex, Hot Repair-Technologie JSPath und Node.js im Backend (ein Technologie-Stack, der mir sehr gut gefällt). Die Anzahl der Sterne für Vue hat die von jQuery übertroffen Die Anzahl der Sterne beweist nichts, zumindest haben wir es bereits getan. Ich kann sehen, dass sich das Front-End-Denken von der vorherigen Dokumentenoperation zur datengesteuerten Entwicklung geändert hat (bei Interesse kann ich später Android, iOS und Vue kombinieren). um diese Denkänderung mit einer kleinen Demo zu demonstrieren. Einige Unternehmen haben sogar damit begonnen, zu versuchen, von dieser Firma hergestelltes Hungry Element zu verwenden, um EasyUI zu ersetzen (Studenten, die Back-End gemacht haben, sollten wissen, dass EasyUI wirklich AV-Qualität hat ...)

JS-Technologie taucht endlos auf, und es gab bereits einen sehr beliebten Artikel über das Erlernen von JS im Jahr 2016. Was für eine Erfahrung das war, es erschreckte viele Menschen sofort zutiefst. Alle konzentrierten sich auf Frameworks und neue Technologien , aber native JS wurde im Regen stehen gelassen, deshalb wollte ich einige grundlegende JS-Themen mit Ihnen teilen. Gemeinsam kommunizieren (Ich hoffe, dass mich alle zum Fliegen mitnehmen, aber lassen Sie mich nicht mit Malaysia Airlines fliegen ...)


Bereich in JavaScript

Eine einfache Frage:

<script>
    var str1 = "hello";
    var str2 = "world";

    function t1() {
        console.log(str1);
        console.log(str2);

        var str2 = "toby";
        console.log(str2);
    }

    //这里会输出什么?
    t1();

</script>
Nach dem Login kopieren

Dies ist ein sehr einfaches JS-Bereichsproblem, aber je mehr Sie das Wort „einfach“ betonen, desto leichter können die Leute ihre Wachsamkeit lockern, was dazu führt, dass einige Schüler ohne nachzudenken antworten

● Hallo

● Welt

● Toby

Aber das Ergebnis ist die Ausgabe

● Hallo

● undefiniert

● toby

Dann ist das seltsam, warum gibt es undefiniert Nein Sollte es Welt sein? Zunächst müssen wir verstehen, dass die Suche nach Variablen dem Prinzip der Nähe folgt, also wird js zuerst suchen die Funktion, und schauen Sie dann nach draußen, wenn sie nicht gefunden werden kann. Es gibt str2 in der Funktion, aber beim Ausführen von console.log(str2) ist str2 undefiniert, also undefiniert


lexikalische Analyse

Um zu wissen, was passiert, müssen Sie wissen, warum, also schauen wir uns noch ein paar Beispiele an

Beispiel 1

<script>
    function t(userName) {
        console.log(userName);//这里输出什么?

        function userName() {
            console.log(&#39;tom&#39;);
        }
    }
    t(&#39;toby&#39;);
</script>
Nach dem Login kopieren

Was ist das Ausgabeergebnis? Das Beispiel scheint sich von dem oben genannten zu unterscheiden. Es fühlt sich an, als würde man zur High-School-Mathematik zurückkehren Wenn sich der Fragetyp ändert, denken einige Schüler möglicherweise, dass es sich um Toby handelt, aber die tatsächliche Ausgabe lautet: Warum funktioniert diese Art von Problem? Diese Formel ist eine lexikalische Analyse in JS. Eine der Aufgaben, die durchgeführt werden müssen, bevor die Funktion in JS ausgeführt wird, ist die lexikalische Analyse Deklarationen, Funktionsdeklarationen analysieren, dann verwenden wir diese Frage, um die Formel anzuwenden

function userName() {
    console.log(&#39;tom&#39;);
}
Nach dem Login kopieren
Wenn t('toby') ausgeführt wird, beginnen zwei Phasen, eine Es ist die Analysephase. Nach der Analyse geht es weiter zur Ausführungsphase

Analysephase:

● In dem Moment, in dem die Funktion ausgeführt wird, wird ein Active Object-Objekt (im Folgenden als AO-Objekt bezeichnet) generiert, das innerhalb einer Funktion gefunden werden kann Geltungsbereich. Zu diesem Zeitpunkt wird der Code wie folgt ausgedrückt: t.AO = {}

● Analyseparameter: Parameter erhalten, Parameternamen als Attribute verwenden und Parameterwerte als Attributwerte, da keine Parameter vorhanden sind, daher wird das Analyseergebnis im Code ausgedrückt: t.AO = {userName: toby}

● Analyse der var-Anweisung: Es gibt keine var-Anweisung in der t-Funktion. überspringen

● Analyse der Funktionsanweisung: Diese Funktionsdeklaration hat ein Attribut mit demselben Namen wie der Funktionsname, der von dieser Funktion überschrieben wird ein Variablentyp im JS-Feld, der im Code ausgedrückt wird als: t.AO = { userName: function userName() {console.log('tom');}}

Ausführungsphase:

Bei der Ausführung von t('toby'), bei der Ausführung von console.log(userName) Wenn t.AO.userName aufgerufen wird, ist das endgültige Ausgabeergebnis die Funktion userName() {console.log('tom' );}

Beispiel 2

Was ist dann die Ausgabe hier? Dies scheint sich vom obigen Beispiel zu unterscheiden, und es ist erneut in Verwirrung geraten ? Haben Sie keine Angst vor Ärger und befolgen Sie den Prozess genau nach der Formel (das obige Beispiel ist detaillierter geschrieben, die folgende Analyse wird einfach geschrieben)

<script>
    function t(userName) {
        console.log(userName);//这里输出什么?

        var userName = function () {
            console.log(&#39;tom&#39;);
        }
    }
    t(&#39;toby&#39;);
</script>
Nach dem Login kopieren
Vor der Analyse müssen Sie zunächst zwei verstehen Konzepte, eines heißt Funktionsdeklaration und das andere heißt Funktionsausdruck

Analysephase:

//这个叫函数声明
function userName() {
    console.log(&#39;tom&#39;);
}

//这个叫函数表达式
var userName = function () {
    console.log('tom');
}
Nach dem Login kopieren
● AO-Objekt erstellen, t.AO = {}

● Analyseparameter: t.AO = {userName: toby}

● 分析var声明: 在AO上,形成一个属性,以var的变量名为属性名,值为undefined,(因为是先分析,后执行,这只是词法分析阶段,并不是执行阶段,分析阶段值都是undefined,如果执行阶段有赋值操作,那值会按照正常赋值改变),也就是说代码应该表示为:t.AO = {userName : undefined},但是还有另外一个原则,那就是如果AO有已经有同名属性,则不影响(也就是什么事都不做),由于分析参数时,AO上已经有userName这个属性了,所以按照这个原则,此时什么事都不做,也就是说,此时按照分析参数时的结果t.AO = {userName : toby}

● 分析函数声明: 此时没有函数声明,略过

执行阶段:

调用t.AO.userName,所以,最后的输出结果是toby

例子3

<script>
    t();
    t2();

    function t() {
        console.log(&#39;toby&#39;);//这里会输出什么?
    }

    var t2 = function () {
        console.log(&#39;hello toby&#39;);//这里会输出什么?
    };
</script>
Nach dem Login kopieren

那么我们再来看一个例子,这下彻底回到高中时代,做了两个例子好像感觉掌握了,结果考试你给来看这个?

答案是,t()输出为toby,t2()则会报错.这又是为什么?

● t()可以调用是因为在词法分析的过程,就已经完成了t函数的分析,所以可以调用

● t2()不能调用是因为在词法分析的阶段,分析到有一个t2声明,在AO上只是形成了一个属性,但是值为undefined

例子4

<script>
    function t(userName) {
        console.log(userName);//这里输出什么?
        function userName() {
            console.log(userName);//这里输出什么?
        }
        userName();
    }
    t(&#39;toby&#39;);
</script>
Nach dem Login kopieren

函数里面套函数,这次竟然又和前面不一样了...这次我不说答案了,直接先套公式走一波

t('toby')的分析和执行阶段

分析阶段:

● 创建AO对象,t.AO = {}

● 分析参数: t.AO = {userName : toby}

● 分析var声明: 有同名属性,不做任何事,还是t.AO = {userName : toby}

● 分析函数声明: 有同名属性,覆盖: t.AO = {userName : function userName() {console.log(userName);}}

执行阶段: t.AO.userName 输出为function userName() {console.log(userName);}}

userName()的分析和执行阶段

这里也要搞清楚两个概念

//执行userName()分析的是
function () {
  console.log(userName);
};

//而不是
var userName = function () {
    console.log(userName);
};
Nach dem Login kopieren

分析阶段:

● 创建AO对象,userName.AO = {}

● 分析参数: 无,略过

● 分析var声明: 无,略过

● 分析函数声明: 无,略过

执行阶段: 因为此时userName.AO = {}是个空对象,无法执行userName.AO.userName,所以会向上一层找,所以输出t.AO.userName的结果,也就是function userName() {console.log(userName);}}

例子5

<script>
    function t(userName) {
        console.log(userName);//这里输出什么?
        var userName = function () {
            console.log(userName);//这里输出什么?
        }
        userName();
    }
    t(&#39;toby&#39;);
</script>
Nach dem Login kopieren

好吧,我保证这个是最后一道...这个输出结果是什么呢?我们只要坚定公式没问题,就一定能得出结果,那么再套公式走一波

t('toby')的分析和执行阶段

分析阶段:

● 创建AO对象,t.AO = {}

● 分析参数: t.AO = {userName : toby}

● 分析var声明: 有同名属性,不做任何事,还是t.AO = {userName : toby}

● 分析函数声明: 无,略过

执行阶段: 执行console.log(userName);时调用t.AO.userName 输出为toby,执行完后,代码继续往下执行,那么就到了进行var的赋值操作(var的分析和执行的区别看例子2中我有解释),此时t.AO = {userName : function userName() {console.log(userName);}}},代码继续往下执行,接着就执行到了userName()

userName()的分析和执行阶段

分析阶段:

● 创建AO对象,userName.AO = {}

● 分析参数: 无,略过

● 分析var声明: 无,略过

● 分析函数声明: 无,略过

执行阶段: 按照例子4我们知道userName.AO是个空对象,所以会往上调用t.AO.userName,所以输出为:function userName() {console.log(userName);}}}


总结

JavaScript作用域会先在自己的AO上找,找不到就到父函数的AO上找,再找不到再找上一层的AO,直到找到window.这样就形成一条链,这条AO链就是JavaScript中的作用域链.JavaScript中有两条很重要的链,一条是作用域链,一条是原型链,

Erklärung dieser Website
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

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

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Verwendung der Typedef-Struktur in der C-Sprache Verwendung der Typedef-Struktur in der C-Sprache May 09, 2024 am 10:15 AM

typedef struct wird in der C-Sprache zum Erstellen von Strukturtypaliasen verwendet, um die Verwendung von Strukturen zu vereinfachen. Es weist einem neuen Datentyp ein Alias ​​auf eine vorhandene Struktur zu, indem es den Strukturalias angibt. Zu den Vorteilen gehören verbesserte Lesbarkeit, Wiederverwendung von Code und Typprüfung. Hinweis: Die Struktur muss vor der Verwendung eines Alias ​​definiert werden. Der Alias ​​muss im Programm eindeutig sein und nur innerhalb des Bereichs gültig sein, in dem er deklariert ist.

So lösen Sie die in Java erwartete Variable So lösen Sie die in Java erwartete Variable May 07, 2024 am 02:48 AM

Variablenerwartungsausnahmen in Java können gelöst werden durch: Initialisierung von Variablen; Verwendung von Nullwerten; Verwendung von Überprüfungen und Zuweisungen;

Vor- und Nachteile von Verschlüssen in js Vor- und Nachteile von Verschlüssen in js May 10, 2024 am 04:39 AM

Zu den Vorteilen von JavaScript-Abschlüssen gehören die Aufrechterhaltung des variablen Bereichs, die Aktivierung von modularem Code, die verzögerte Ausführung und die Ereignisbehandlung. Zu den Nachteilen zählen Speicherverluste, erhöhte Komplexität, Leistungsaufwand und Auswirkungen der Bereichskette.

Was bedeutet include in c++? Was bedeutet include in c++? May 09, 2024 am 01:45 AM

Die Präprozessoranweisung #include in C++ fügt den Inhalt einer externen Quelldatei in die aktuelle Quelldatei ein und kopiert ihren Inhalt an die entsprechende Stelle in der aktuellen Quelldatei. Wird hauptsächlich zum Einschließen von Header-Dateien verwendet, die im Code benötigte Deklarationen enthalten, z. B. #include <iostream>, um Standard-Eingabe-/Ausgabefunktionen einzubinden.

C++-Smartpointer: eine umfassende Analyse ihres Lebenszyklus C++-Smartpointer: eine umfassende Analyse ihres Lebenszyklus May 09, 2024 am 11:06 AM

Lebenszyklus von C++-Smartpointern: Erstellung: Smartpointer werden erstellt, wenn Speicher zugewiesen wird. Eigentumsübertragung: Übertragen Sie das Eigentum durch einen Umzugsvorgang. Freigabe: Speicher wird freigegeben, wenn ein Smart Pointer den Gültigkeitsbereich verlässt oder explizit freigegeben wird. Objektzerstörung: Wenn das Objekt, auf das gezeigt wird, zerstört wird, wird der intelligente Zeiger zu einem ungültigen Zeiger.

Können die Definition und der Aufruf von Funktionen in C++ verschachtelt werden? Können die Definition und der Aufruf von Funktionen in C++ verschachtelt werden? May 06, 2024 pm 06:36 PM

Dürfen. C++ erlaubt verschachtelte Funktionsdefinitionen und Aufrufe. Externe Funktionen können integrierte Funktionen definieren und interne Funktionen können direkt innerhalb des Bereichs aufgerufen werden. Verschachtelte Funktionen verbessern die Kapselung, Wiederverwendbarkeit und Bereichskontrolle. Interne Funktionen können jedoch nicht direkt auf lokale Variablen externer Funktionen zugreifen, und der Rückgabewerttyp muss mit der Deklaration der externen Funktion übereinstimmen. Interne Funktionen können nicht selbstrekursiv sein.

Der Unterschied zwischen let und var in vue Der Unterschied zwischen let und var in vue May 08, 2024 pm 04:21 PM

In Vue gibt es beim Deklarieren von Variablen zwischen let und var einen Unterschied im Gültigkeitsbereich: Gültigkeitsbereich: var hat einen globalen Gültigkeitsbereich und let hat einen Gültigkeitsbereich auf Blockebene. Bereich auf Blockebene: var erstellt keinen Bereich auf Blockebene, let erstellt einen Bereich auf Blockebene. Neudeklaration: var ermöglicht die Neudeklaration von Variablen im gleichen Bereich, let jedoch nicht.

Es gibt mehrere Situationen, auf die dies in js hinweist Es gibt mehrere Situationen, auf die dies in js hinweist May 06, 2024 pm 02:03 PM

Zu den Zeigertypen gehören in JavaScript: 1. Globales Objekt; 3. Konstruktoraufruf; 5. Pfeilfunktion (erbt dies); Darüber hinaus können Sie mit den Methoden bind(), call() und apply() explizit festlegen, worauf dies hinweist.

See all articles