2016-08-01 49 views
1

Ich habe das stundenlang ohne Erfolg geblockt.Warum verursacht dieser Aufruf einer einfachen Hilfsfunktion eine Endlosschleife?

Die folgenden Code überprüft, ob jede Zahl in einer Reihe von Zahlen und keine sich wiederholenden Stellen hat (111 sollte false zurückkehren; 123 sollte true zurückkehren) und eine Reihe von Zahlen in allen der Reihe zurück, die keine sich wiederholenden Ziffern enthalten.

Das Array sollte mit Werten gefüllt werden, die die Hilfsfunktion als true für jeden Wert im Array zurückgibt, aber ausgeführt noRepeats() verursacht eine Endlosschleife oder ein langes Array von 1s. Was verursacht das?

// DO NOT RUN AS IS; POTENTIAL INFINITE LOOP 
 

 
var noRepeatDigits = function (n) { 
 
    n = n.toString(); 
 
    for (i = 0 ; i < n.length ; i ++) { 
 
    for (j = i + 1 ; j < n.length ; j ++) { 
 
     if (n.charAt(i) === n.charAt(j)) { 
 
     return false; 
 
     } 
 
    } 
 
    } 
 
    return true; 
 
}; 
 

 
console.log(noRepeatDigits(113)); // false 
 
console.log(noRepeatDigits(123)); // true 
 

 
var noRepeats = function (n1, n2) { 
 
    var arr = []; 
 
    for (i = n1 ; i <= n2 ; i ++) { 
 
    if (noRepeatDigits(i)) { 
 
     arr.push(i); 
 
    } 
 
    } 
 
    return arr; 
 
}; 
 

 
console.log(noRepeats(1, 100));

+2

Well. Setzen Sie einen Haltepunkt und debuggen Sie Ihren Code. – Tomalak

Antwort

4

Sie haben vergessen zu var i, so der Iterator ist global und die beiden Funktionen sie gegenseitig überschreiben. Dies verursacht bestenfalls ein unerwartetes Verhalten, im schlimmsten Fall eine Endlosschleife.

auch immer Sie Ihre noRepeatDigits Funktion viel vereinfachen kann:

noRepeatDigits = function(n) { 
    return !n.toString().match(/(.).*?\1/); 
}; 

Diese effektiv macht, was Ihre ursprüngliche Funktion hat, sondern entlastet die schwere Arbeit eingebaut, Funktionen auf tieferer Ebene, die schneller sind deutlich allgemein gesprochen .

+0

Das Deklarieren von 'i' als lokale Variable mit' var i' löste mein Problem, danke. Die Verwendung von Regex Matching vereinfacht auch die Dinge. – JBeck

2

Dies ist ein Addon zur Antwort von Niet the Dark Absol.

Wie von ihm gezeigt wurde das unerwartete Verhalten durch die Variablen in Ihrer Schleife verursacht. Ich würde Ihnen empfehlen, den "use strict"; Hinweis oben auf Ihr Javascript zu setzen. Auf diese Weise werden Sie nicht wieder den gleichen Fehler machen.

Beispiel:

"use strict"; 
// DO NOT RUN AS IS; POTENTIAL INFINITE LOOP 

var noRepeatDigits = function (n) { 
    n = n.toString(); 
    for (i = 0 ; i < n.length ; i ++) { 
     for (var j = i + 1 ; j < n.length ; j ++) { 
      if (n.charAt(i) === n.charAt(j)) { 
       return false; 
      } 
     } 
    } 
    return true; 
}; 

Zitat: Konvertieren Fehler in Fehler

Strict-Modus ändert einige zuvor akzeptiert Fehler in Fehler. JavaScript wurde entwickelt, um für Anfänger Anfänger leicht zu sein, und manchmal gibt es Operationen, die Fehler nicht Fehler sein sollten Semantik. Manchmal behebt dies das unmittelbare Problem, aber manchmal dies schafft in Zukunft schlimmere Probleme. Strict-Modus behandelt diese Fehler als Fehler, so dass sie entdeckt und umgehend behoben werden.

Erstens, strikte Modus macht es unmöglich, versehentlich globale Variablen zu erstellen. Bei normalem JavaScript wird eine Variable in einer Zuweisung falsch beschriftet erstellt eine neue Eigenschaft auf dem globalen Objekt und weiterhin " " (obwohl zukünftige Fehler möglich ist: wahrscheinlich, in modernen JavaScript). Zuordnungen, die versehentlich globale Variablen statt throw im Strict-Modus schaffen würde:

See:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

+0

@JamesBecker könnte dich auch interessieren. –

+0

Ich brauchte jemanden, der mir das sagte. Ich wusste von "strict", aber niemand, den ich kenne, implementiert es. Vielleicht sollte ich bessere Freunde finden. Vielen Dank! – JBeck