2017-09-29 2 views
2

Ich bin irgendwie neu in Javascript und heute arbeitete ich an einer Funktion, die im Grunde einen Wert schaltet und es als Alarm anzeigt, aber ich stolperte über ein seltsames Verhalten von JavaScript bezogen zu wahr/falsch und 0/1.true/false vs int in JavaScript (unerwartetes Verhalten)

Der folgende Code, wenn der Benutzer auf Toggle-Anker-Link klickt, es scheint nicht, den Wert und den Alarm zu wechseln gibt immer „true“ (was ich geschehen dachte sollte):

document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>'+ document.body.innerHTML; 
function f() { 
    this.status = true; 
    var btn = document.getElementById("toggle") 
    btn.addEventListener("click",() => { 
     if (this.status == true) { 
      alert(this.status) 
      this.status = false; 
     } else { 
      alert(this.status) 
      this.status = true; 
     } 

    }, false) 
} 

f() 

Aber wenn ich 0 und 1 anstelle von wahr/falsch verwende, funktioniert der Code aus irgendeinem Grund.

document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>' +document.body.innerHTML; 

function f() { 
    this.status = 1; 
    var btn = document.getElementById("toggle") 
    btn.addEventListener("click",()=>{ 
    if(this.status==1){ 
     alert(this.status) 
     this.status = 0; 
    }else{ 
     alert(this.status) 
     this.status = 1; 
     } 

    },false) 
} 

f() 

Ich habe keine Ahnung, was hier vor sich geht, dieser Zeiger wegen this Ist i in der Funktion oder etwas bin mit ?.

+1

, warum Sie nicht === statt == benutzen? – zhuravlyov

+0

JavaScript hat eine komplexere Vorstellung von Gleichheit, als Sie vielleicht in anderen Sprachen kennen, aber es ist zum Glück eine sehr gut verstandene Vorstellung; Schauen Sie sich [diesen Artikel] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness) für eine Einführung an – Hamms

Antwort

4

Das Problem ist, dass Ihre Funktion f ohnegenannt wirdso bezieht sich die this auf die window object, die bereits eine hat.

Sie können dies sehen, ob Sie seine Art zu drucken:

function f() { 
 
    this.status = true; 
 
    console.log(typeof this.status); 
 
} 
 

 
f()

Beachten Sie, wie das Ergebnis ist string statt der erwarteten boolean.

Aber wenn man es anders nennen:

function f() { 
 
    this.myprop = true; 
 
    console.log(typeof this.myprop); 
 
} 
 

 
f()

Es ergibt sich der richtige Typ.

Um es zu arbeiten, müssen Sie nur seinen Namen ändern.Aber die ifelse Logik müssen Sie die boolean invertieren in eine ! (nicht) gedreht werden, die den Code viel vereinfacht:

document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>' + document.body.innerHTML; 
 

 
function f() { 
 
    this.myStatus = true; 
 
    var btn = document.getElementById("toggle"); 
 
    
 
    btn.addEventListener("click",() => { 
 
    this.myStatus = !this.myStatus; //here the value is inverted only with the ! (not) 
 
    console.log(this.myStatus); 
 
    }, false); 
 
} 
 

 
f();

Aber mit dem window Objekt abgeraten wird, für Gründe ähnlich wie die, die Sie erlebt haben, und die myStatus Eigenschaft wird immer noch dort gespeichert.

Sie die Lösung mehr etwas verbessern kann:

document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>' + document.body.innerHTML; 
 

 
function f() { 
 
    let myStatus = true; 
 
    var btn = document.getElementById("toggle"); 
 
    
 
    btn.addEventListener("click",() => { 
 
    myStatus = !myStatus; //here the value is inverted only with the ! (not) 
 
    console.log(myStatus); 
 
    }, false); 
 
} 
 

 
f();

Auch nicht die Aussagen mit den Semikolons zu beenden vergessen, bemerkte ich, dass man von ihnen fast keine hatten.

+0

Beachten Sie, dass Sie myStatus immer noch zum Fensterobjekt hinzufügen, was nicht unbedingt eine großartige Idee ist, es sei denn, Sie tun es absichtlich und können artikulieren, warum Sie es dort haben wollen. – Ben

+0

auf der Seite beachten Sie, was ist der Unterschied zwischen "Let" und "Var". Warum hast du im letzten Snippet 'let' für myStatus und' var' für btn benutzt? –

+0

@ rov.er 'let' garantiert Ihnen Geltungsbereich, während' var' dies nicht tut. Es funktioniert auch besser in Verschlüssen und anderen kleinen Details. Überprüfen Sie die Dokumentation [hier] (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let) – Isac

-1

document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>'+ document.body.innerHTML; 
 
function f() { 
 
    let status = true; 
 
    let btn = document.getElementById("toggle"); 
 
    btn.addEventListener("click",() => { 
 
     if (status === true) { 
 
      alert(status); 
 
      status = false; 
 
     } else { 
 
      alert(status); 
 
      status = true; 
 
     } 
 

 
    }, false) 
 
} 
 

 
f();

0

Da Sie JavaScript neu sind Sie wahrscheinlich nicht gehört haben, aber man sollte know when to use === instead of == (Tipp: immer).

Auf den Punkt gebracht, weil JavaScript is weakly/un-typed kann es schwierig sein zu wissen, ob Sie tatsächlich sind zwei von der gleichen Sache (Zahlen) oder zwei verschiedene Dinge (Anzahl und Objekt) zu vergleichen:

new Number(10) == 10 // true 
new Number(10) === 10 // false 

Denn:

typeof Number(10) // returns number 
typeof 10 // returns number 
typeof new Number(10) // returns object 

^Obiges Beispiel von https://coderwall.com/p/bqurhg/why-always-use-in-javascript

+0

nicht unbedingt "immer" – DragonKnight

+0

@DragonKnight können Sie das bitte ausarbeiten? –

0

Andere Leute haben einige gute Antworten gepostet, aber hier sind meine zwei Cent.

Sie können eine lokale Variable in Ihrer Funktion initialisieren, die einen Wert initialisiert und dann auf diesen Wert wechselt, wenn auf die Schaltfläche geklickt wird. Ihre Verwendung der Notation this scheint hier nicht notwendig zu sein.

document.body.innerHTML = '<a href="#" id="toggle"> toggle </a>'+ document.body.innerHTML; 
function f() { 
    var status = true; 
    var btn = document.getElementById("toggle") 
    btn.addEventListener("click",() => { 
     if (status === true) { 
      alert(status) 
      status = false; 
     } else { 
      alert(status) 
      status = true; 
     } 

    }, false); 
} 

f(); 

Wenn Sie dies verwenden, wissen Sie immer, worauf Sie sich beziehen. Wie Isac darauf hingewiesen hat, bezog sich Ihr this auf das Dokumentfenster, das anscheinend ein Problem war.

Codepen:

https://codepen.io/foozie3moons/pen/gGRBxZ?editors=0010