Inline-Handler
Ein sehr häufiges, noch nicht beschriebenes Problem, auf das Front-End-Programmierer oft stoßen, ist der Bereich, der für einen Inline-Event-Handler im HTML sichtbar ist - zum Beispiel mit
<button onclick="foo()"></button>
Der Geltungsbereich der Variablen, die eine on*
Attribut kann referenzieren muss entweder sein:
- global (funktionierende Inline-Handler verweisen fast immer auf globale Variablen)
- eine Eigenschaft des Dokuments (z. B,
querySelector
als eigenständige Variable zeigt auf document.querySelector
; selten)
- eine Eigenschaft des Elements, an das der Handler gebunden ist (wie oben; selten)
Andernfalls erhalten Sie einen ReferenceError, wenn der Handler aufgerufen wird. Wenn der Inline-Handler zum Beispiel auf eine Funktion verweist, die definiert ist innerhalb window.onload
o $(function() {
wird der Verweis fehlschlagen, da der Inline-Handler nur auf Variablen im globalen Bereich verweisen darf und die Funktion nicht global ist:
window.addEventListener('DOMContentLoaded', () => {
function foo() {
console.log('foo running');
}
});
<button onclick="foo()">click</button>
Eigenschaften des document
und Eigenschaften des Elements, an das der Handler angehängt ist, können auch als eigenständige Variablen innerhalb von Inline-Handlern referenziert werden, da Inline-Handler aufgerufen werden innerhalb von zwei with
Blöcke eine für die document
, eine für das Element. Die Geltungskette der Variablen innerhalb dieser Handler lautet extrem unintuitiv und ein funktionierender Event-Handler wird wahrscheinlich erfordern, dass eine Funktion global ist (und unnötige globale Verschmutzung sollte wahrscheinlich vermieden werden ).
Da die Scope-Kette innerhalb von Inline-Handlern so seltsam und da Inline-Handler globale Verschmutzung benötigen, um zu funktionieren, und da Inline-Handler manchmal hässliches String-Escaping bei der Übergabe von Argumenten benötigen, ist es wahrscheinlich einfacher, sie zu vermeiden. Fügen Sie stattdessen Event-Handler mit Javascript an (wie mit addEventListener
) und nicht mit HTML-Markup.
function foo() {
console.log('foo running');
}
document.querySelector('.my-button').addEventListener('click', foo);
<button class="my-button">click</button>
Module ( <script type="module">
)
Im Gegensatz zu den normalen <script>
Tags, die auf der obersten Ebene ausgeführt werden, läuft der Code in ES6-Modulen in seinem eigenen privaten Bereich. Eine Variable, die am Anfang eines normalen <script>
Tag ist global, so dass Sie es in anderen Anwendungen referenzieren können. <script>
Tags, etwa so:
<script>
const foo = 'foo';
</script>
<script>
console.log(foo);
</script>
Die oberste Ebene eines ES6-Moduls ist jedoch no global. Eine Variable, die am Anfang eines ES6-Moduls deklariert ist, ist nur innerhalb dieses Moduls sichtbar, es sei denn, die Variable ist explizit export
oder wenn sie nicht einer Eigenschaft des globalen Objekts zugewiesen ist.
<script type="module">
const foo = 'foo';
</script>
<script>
// Can't access foo here, because the other script is a module
console.log(typeof foo);
</script>
Die oberste Ebene eines ES6-Moduls ist ähnlich wie das Innere eines IIFE auf der obersten Ebene in einer normalen <script>
. Das Modul kann auf alle Variablen verweisen, die global sind, und nichts kann auf etwas innerhalb des Moduls verweisen, es sei denn, das Modul ist ausdrücklich dafür vorgesehen.
5 Stimmen
Hier ist eine weitere schöne Link dieses Thema im Auge zu behalten: " Erläuterung von JavaScript-Bereich und -Schließungen ".
10 Stimmen
Hier ist ein Artikel, der dies sehr gut erklärt. Alles, was Sie über den Umfang von Javascript-Variablen wissen müssen
3 Stimmen
Le site zuvor erwähnt E-Book von Kyle Simpson ist auf Github zu lesen, und es sagt Ihnen alles, was Sie über JavaScript Scopes & Closures wissen müssen. Sie können es hier finden: github.com/getify/You-Dont-Know-JS/blob/master/ Es ist Teil des Buchreihe "Du kennst JS nicht" die für alle geeignet ist, die mehr über JavaScript wissen möchten.
0 Stimmen
var
Regeln. javascript braucht nicht den "Zusatz" von 'const' und 'let', die gegen seinen Geist sind. - Ich weiß, dass diese beiden nicht Teil Ihrer Frage sind - musste dies hinzufügen, nachdem ich sah, dass so viele sie "schieben".