Heim Web-Frontend js-Tutorial JavaScript Advanced Series – Umfang und Namespace

JavaScript Advanced Series – Umfang und Namespace

Feb 08, 2017 am 09:35 AM

  • Implizite globale Variablen

  • Lokale Variablen

  • Variablendeklaration-Heben (Hoisting)

  • Namensauflösungsreihenfolge

  • Namespace

  • Fazit

Obwohl JavaScript unterstützt wird Codeausschnitte, die durch ein Paar geschweifte Klammern erstellt werden, unterstützen nicht den Bereich auf Blockebene, sondern nur den Funktionsbereich.

function test() { // 一个作用域
    for(var i = 0; i < 10; i++) { // 不是一个作用域
        // count
    }
    console.log(i); // 10
}
Nach dem Login kopieren

Anmerkung des Übersetzers: Wenn sich die linke Klammer des Rückgabeobjekts und der Rückgabe nicht in derselben Zeile befinden, tritt ein Fehler auf.

(Hinweis: Wenn es sich nicht in einer Zuweisungsanweisung, sondern in einem Rückgabeausdruck oder Funktionsparameter befindet, wird {...} als Codesegment analysiert, nicht als wörtliche Syntaxanalyse von Das Objekt. Wenn das automatische Einfügen von Semikolons berücksichtigt wird, kann dies zu einigen subtilen Fehlern führen.

// 译者注:下面输出 undefined
function add(a, b) {
    return 
        a + b;
}
console.log(add(1, 2));
Nach dem Login kopieren

Es gibt keine explizite Namespace-Definition in JavaScript, was bedeutet, dass alle Objekte unter definiert sind ein weltweit gemeinsam genutzter Namensraum.

Jedes Mal, wenn auf eine Variable verwiesen wird, durchläuft JavaScript den gesamten Bereich nach oben, bis es die Variable findet. Wenn der globale Gültigkeitsbereich erreicht ist, die Variable aber immer noch nicht gefunden wird, wird eine ReferenceError-Ausnahme ausgelöst.

Implizite globale Variablen

// 脚本 A
foo = &#39;42&#39;;

// 脚本 B
var foo = &#39;42&#39;
Nach dem Login kopieren

Die beiden oben genannten Skripte haben unterschiedliche Auswirkungen. Skript A definiert die Variable foo im globalen Bereich, während Skript B die Variable foo im aktuellen Bereich definiert.

Auch hier ist der obige Effekt völlig anders: Die Deklaration von Variablen ohne Verwendung von var führt zur Erstellung impliziter globaler Variablen.

// 全局作用域
var foo = 42;
function test() {
    // 局部作用域
    foo = 21;
}
test();
foo; // 21
Nach dem Login kopieren

Das Deklarieren der foo-Variablen ohne Verwendung des Schlüsselworts var innerhalb des Funktionstests überschreibt die externe Variable mit demselben Namen. Das scheint auf den ersten Blick kein großes Problem zu sein, aber wenn Sie Tausende von Codezeilen haben, kann die Deklaration von Variablen ohne Verwendung von var zu Fehlern führen, die schwer aufzuspüren sind.

// 全局作用域
var items = [/* 数组 */];
for(var i = 0; i < 10; i++) {
    subLoop();
}

function subLoop() {
    // subLoop 函数作用域
    for(i = 0; i < 10; i++) { // 没有使用 var 声明变量
        // 干活
    }
}
Nach dem Login kopieren

Die äußere Schleife wird nach dem ersten Aufruf von subLoop beendet, da subLoop die globale Variable i überschreibt. Dieser Fehler kann vermieden werden, indem die Variable in der zweiten for-Schleife mit var deklariert wird. Lassen Sie das Schlüsselwort var niemals weg, wenn Sie eine Variable deklarieren, es sei denn, dies ist das gewünschte Verhalten, das sich auf den äußeren Bereich auswirkt.

Lokale Variablen

Lokale Variablen in JavaScript können nur auf zwei Arten deklariert werden: eine als Funktionsparameter und die andere über das Schlüsselwort var.

// 全局变量
var foo = 1;
var bar = 2;
var i = 2;

function test(i) {
    // 函数 test 内的局部作用域
    i = 5;

    var foo = 3;
    bar = 4;
}
test(10);
Nach dem Login kopieren

foo und i sind lokale Variablen innerhalb des Funktionstests, und die Zuweisung an bar überschreibt die gleichnamige Variable im globalen Bereich.

Variablendeklaration hochziehen (Hoisting)

JavaScript hebt Variablendeklarationen hoch. Dies bedeutet, dass sowohl var-Ausdrücke als auch Funktionsdeklarationen an die Spitze des aktuellen Bereichs gehoben werden.

bar();
var bar = function() {};
var someValue = 42;

test();
function test(data) {
    if (false) {
        goo = 1;

    } else {
        var goo = 2;
    }
    for(var i = 0; i < 100; i++) {
        var e = data[i];
    }
}
Nach dem Login kopieren

Der obige Code wird vor der Ausführung konvertiert. JavaScript hebt Variablenausdrücke und Funktionsdeklarationen an die Spitze des aktuellen Bereichs.

// var 表达式被移动到这里
var bar, someValue; // 缺省值是 &#39;undefined&#39;

// 函数声明也会提升
function test(data) {
    var goo, i, e; // 没有块级作用域,这些变量被移动到函数顶部
    if (false) {
        goo = 1;

    } else {
        goo = 2;
    }
    for(i = 0; i < 100; i++) {
        e = data[i];
    }
}

bar(); // 出错:TypeError,因为 bar 依然是 &#39;undefined&#39;
someValue = 42; // 赋值语句不会被提升规则(hoisting)影响
bar = function() {};

test();
Nach dem Login kopieren

Das Fehlen eines Blockbereichs führt nicht nur dazu, dass var-Ausdrücke von innerhalb der Schleife nach außen verschoben werden, sondern macht auch einige if-Ausdrücke schwerer lesbar.

Im Originalcode scheint der if-Ausdruck die globale Variable goo zu ändern, tatsächlich ändert er jedoch die lokale Variable, nachdem die Heraufstufungsregel angewendet wurde.

Ohne Kenntnisse über das Heben scheint der folgende Code eine ReferenceError-Ausnahme auszulösen.

// 检查 SomeImportantThing 是否已经被初始化
if (!SomeImportantThing) {
    var SomeImportantThing = {};
}
Nach dem Login kopieren

Eigentlich funktioniert der obige Code einwandfrei, da der var-Ausdruck an die Spitze des globalen Bereichs gehoben wird.

var SomeImportantThing;

// 其它一些代码,可能会初始化 SomeImportantThing,也可能不会

// 检查是否已经被初始化
if (!SomeImportantThing) {
    SomeImportantThing = {};
}
Nach dem Login kopieren

Anmerkung des Übersetzers: Auf der Nettuts+-Website gibt es einen Artikel, der das Heben vorstellt, und der darin enthaltene Code ist sehr aufschlussreich.

// 译者注:来自 Nettuts+ 的一段代码,生动的阐述了 JavaScript 中变量声明提升规则
var myvar = &#39;my value&#39;;  

(function() {  
    alert(myvar); // undefined  
    var myvar = &#39;local value&#39;;  
})();
Nach dem Login kopieren

Reihenfolge der Namensauflösung


Alle Bereiche in JavaScript, einschließlich des globalen Bereichs, haben einen speziellen Namen, der auf das aktuelle Objekt verweist. Es gibt auch eine Standardvariable arguments im Funktionsumfang, die die an die Funktion übergebenen Parameter enthält. Beim Zugriff auf die Variable foo innerhalb einer Funktion sucht JavaScript beispielsweise in der folgenden Reihenfolge:

  1. Ob es im aktuellen Bereich eine Definition von var foo gibt.

  2. Ob die formalen Parameter der Funktion den Foo-Namen verwenden.

  3. Ob die Funktion selbst foo heißt.

  4. Kehren Sie zum vorherigen Umfang zurück und beginnen Sie erneut bei Nr. 1.

Namespace

Ein häufiger Fehler, der dadurch verursacht wird, dass es nur einen globalen Bereich gibt, sind Namenskonflikte. In JavaScript lässt sich dies leicht mit anonymen Wrappern lösen.

(Hinweis: Benutzerdefinierte Argumentparameter verhindern die Erstellung nativer Argumentobjekte.)

(function() {
    // 函数创建一个命名空间

    window.foo = function() {
        // 对外公开的函数,创建了闭包
    };

})(); // 立即执行此匿名函数
Nach dem Login kopieren

Anonyme Funktionen gelten als Ausdrücke und müssen daher aus Gründen der Aufrufbarkeit zuerst ausgeführt werden.

( // 小括号内的函数首先被执行
function() {}
) // 并且返回函数对象
() // 调用上面的执行结果,也就是函数对象
Nach dem Login kopieren

Es gibt einige andere Möglichkeiten, Funktionsausdrücke aufzurufen. Die folgenden beiden Methoden haben beispielsweise eine unterschiedliche Syntax, aber die Wirkung ist genau die gleiche.

// 另外两种方式
+function(){}();
(function(){}());
Nach dem Login kopieren

Fazit


Es wird empfohlen, anonyme Wrapper (Anmerkung des Übersetzers: selbstausführende anonyme Funktionen) zu verwenden, um Namespaces zu erstellen. Dies verhindert nicht nur Namenskonflikte, sondern erleichtert auch die Modularisierung des Programms.

Außerdem gilt die Verwendung globaler Variablen als schlechte Praxis. Ein solcher Code ist fehleranfällig und kostspielig in der Wartung.

Das Obige ist der Inhalt der erweiterten JavaScript-Serie – Umfang und Namespace. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (www.php.cn).


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ßer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌

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.

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.

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.

See all articles