2016-12-10 2 views
2

Wie manipuliert JS-Engine nicht deklarierte Variable?

<!DOCTYPE html> 
 
<html> 
 
    <head> 
 
    <meta lan="en-us" charset="UTF-8"> 
 
    </head> 
 
    <body> 
 

 
    <p>Counting with a local variable.</p> 
 

 
    <p id="demo"></p> 
 
    <button type="button" onclick="myFunction('+')">Count +</button> 
 
    <button type="button" onclick="myFunction('-')">Count -</button> 
 

 
    <script> 
 
     document.getElementById("demo").innerHTML = 0; 
 
     function add(number){ 
 
     var counter = 0; 
 
     return function() {return counter += number;} 
 
     } 
 
     function sub(number){ 
 
     var counter = 0; 
 
     return function() {return counter -= number;} 
 
     } 
 

 
     var counterIncr = add(1); 
 
     var counterDicr = sub(1); 
 

 
     function myFunction(s){ 
 
     if(s == "+"){ 
 
      /*this.*/counter1 = counterIncr(); 
 
     } 
 
     else if (s == "-"){ 
 
      /*this.*/counter2 = counterDicr(); 
 
     } 
 

 
     if(!counter2 && counter1){ 
 
      document.getElementById("demo").innerHTML = counter1; 
 
     } 
 
     else if(!counter1 && counter2){ 
 
      document.getElementById("demo").innerHTML = counter2; 
 
     } 
 
     else if(counter1 && counter2){ 
 
      document.getElementById("demo").innerHTML = (counter1 + counter2); 
 
     } 
 
     } 
 
    </script> 
 

 
    </body> 
 
</html>

Während meiner Studie über JS Schließungen habe ich ein W3C Beispiel erweitert, eine HTML-Seite mit zwei Tasten zu implementieren. Das Beispiel hat nur einen Knopf. Die erste Schaltfläche erhöht den Zähler-Klick und die zweite Schaltfläche verringert den Zähler. Eine Funktion "myFunction" wird definiert, die zwei Variablen "counter1" und counter2 "verwendet, um den Job auszuführen. Diese Variablen wurden als this.counter1 und this.counter2 deklariert und die Implementierung dieser Seite funktioniert wie erwartet. Meine Frage: Wenn ich "this" von counter1 und counter2 declaration weglasse (... nur zum Spaß) funktioniert meine Seite immer noch (sicher nicht im strikten Modus) aber nur wenn beide Buttons einmal angeklickt wurden. Wie könnte dieses Verhalten erklärt werden oder wie funktioniert JS? ? Motor manipuliert (behandelt) nicht deklarierten Variablen unter der Haube

Antwort

1

eine Variable, die nicht explizit deklariert wird, wird immer eine globale Variable automatisch sein:

function myFunction() { 
 
    // explicitly declared variable (local) 
 
    var explitic = "foo"; 
 
    
 
    // implicitly declared variable (global) 
 
    implicit = "bar"; 
 
} 
 
    
 
myFunction(); // call function 
 

 
console.log(typeof explicit); // prints "undefined" since local 
 
console.log(typeof implicit); // prints "string" since global

Weitere Beispiele here.

Strict-Modus, auf der anderen Seite akzeptiert keine implizit Variablen überhaupt erklärt:

"use strict"; 
 

 
var explicitGlobal = "foo"; 
 

 
function myFunction() { 
 
    // works because explicitGlobal is already defined 
 
    explicitGlobal = "foo2"; 
 

 
    // Uncaught ReferenceError: implicit is not defined 
 
    implicit = "bar"; 
 
} 
 
     
 
myFunction();

1

Variablen, die „nicht angemeldete“ sind, werden als globale Variablen implizit zugewiesen (und Eigenschaften des globalen Objekts) im nicht-strikten ("schlampigen") Modus. Sie befinden sich im Sloppy-Modus, weshalb Ihr Code funktioniert.

;(function sloppy() { 
 
    sloppyVar = 'sloppy' 
 
})() 
 

 
console.log(sloppyVar) //=> 'sloppy' 
 

 
;(function strict() { 
 
    "use strict"; 
 
    strictVar = 'strict' //=> throws ReferenceError 
 
})()

Sie sollten wahrscheinlich this verwenden sowieso nicht auf das globale Objekt zu beziehen, weil das als strenger Modus ist veraltet.

;(function sloppy() { 
 
    console.log(this === window) //=> true 
 
})() 
 

 
;(function strict() { 
 
    "use strict"; 
 
    console.log(this) //=> undefined 
 
})()

Es ist richtig, die window Referenz zu verwenden, wenn Sie im Browser arbeiten, so stattdessen würden Sie schreiben:

window.globalVar = 'stuff' 
+0

Könnte die schlampig Modus irgendwie erklären, warum Die Seite zeigt den korrekten (nach Klicks) Wert des Zählers an, nachdem beide Tasten einmal angeklickt wurden. Warum verhält sich die Seite so, als würde sie keine ersten Klicks "fühlen"? – Gfour

Verwandte Themen