2017-05-04 1 views
0

ich einen Fehler bekam während diesen Code verwendenJavaScript - Uncaught Auslöser Range: Maximale Call-Stack-Größe überschritten

var book = { 
     year: 2004, 
     edition: 1 
    }; 

    Object.defineProperty(book, "year", { 
     get: function(){ 
      return this.year; 
     }, 
     set: function(newValue){ 

      if (newValue > 2004) { 
       this.year = newValue; 
       this.edition += newValue - 2004; 
      } 
     } 
    }); 

    book.year = 2005; 
    alert(book.edition); 

Die Warnung mir gesagt, dass der Fehler bei Object.set passiert ist [als Jahr] this.year = newValue; Ich bin verwirrt, dass Warum wird dieser Fehler durch die Einstellung des Jahres verursacht?

Antwort

0

Sie definieren einen Getter und Setter für year. Der Setzer ruft bei der Zuweisung an this.year = newValue; den Setzer erneut auf, was zu einer Endlosschleife führt. Sie müssten beispielsweise eine benutzerdefinierte Eigenschaft _year definieren und den Jahrzustand dort beibehalten:

var book = { 
    edition: 1 
}; 

Object.defineProperty(book, "_year", { 
    value: 2004, 
    enumerable: false, // Hide it when looping the object 
    writeable: true, 
    configurable: true 
}); 

Object.defineProperty(book, "year", { 
    get: function(){ 
     return this.year; 
    }, 
    set: function(newValue){ 

     if (newValue > 2004) { 
      this._year = newValue; 
      this.edition += newValue - 2004; 
     } 
    }, 
    enumerable: true, // Show this when looping 
    configurable: true 
}); 

book.year = 2005; 
alert(book.edition); 

console.log(Object.keys(book)); // ['edition', 'year'] 
1

Wenn Sie die Eigenschaft year festlegen, rufen Sie implizit die Funktion set auf.

Die set-Funktion setzt die year-Eigenschaft (wenn der Wert> 2004 ist).

So:

  1. Sie legen das Jahr Eigentum bis 2005
  2. Die eingestellte Funktion setzt das Jahr Eigentum bis 2005
  3. GOTO 2 und Schleife für die Unendlichkeit
0

Hier ist die Reihenfolge der Ereignisse, die diesen Fehler verursachen:

  • Sie setzen die year des Buches.
  • Da es sich um eine Eigenschaft handelt, wird der Wert an Ihre Setter-Funktion übergeben.
  • Die Prüfung wird durchgeführt - da in diesem Fall ist es wahr, wird gesetzt.
  • Uh oh - da Sie nur gesetzt haben, wird der Setter erneut ausgeführt.
  • Die Prüfung wird fortgesetzt, da sie immer wieder den gleichen Wert erhält.
  • Ihr Browser beginnt für immer zu loopen, hat keinen Speicher mehr und fällt in einen großen Haufen über.

Um dies zu vermeiden, müssen Sie den aktuellen Wert in einem separaten Feld des Objekts speichern (z this._year), und dann wird dieser Wert Ihrer Getter Rückkehr haben. Hier ein Beispiel:

var book = { 
    _year: 2004, 
    edition: 1 
}; 

Object.defineProperty(book, "year", { 
    get: function() { 
     return this._year; 
    }, 
    set: function(newValue) { 
     if (newValue > 2004) { 
      this._year = newValue; 
      this.edition += newValue - 2004; 
     } 
    } 
}); 

book.year = 2005; 
alert(book.edition); 
Verwandte Themen