2016-05-28 13 views
7

Próbuję dowiedzieć się i ustawić w obiektu JavaScript na które starałemgetter setter Maksymalny rozmiar stosu wywołań przekroczyła błąd

function ab(n){this.name=n;}; 
var c= new ab("abcde"); 
console.log(c); 
Object.defineProperty(c, 'name', { 
    get: function() { 
     return name; 
    }, 
    set: function(Name) { 
     this.name = Name; 
     } 
}); 
c.name="xyz"; 
console.log(c.name); 

Oto jestem pierwszy podejmowania obiektu za pomocą konstruktora, a następnie używając get i set. Ale otrzymuję komunikat "Przekroczono maksymalny rozmiar stosu połączeń". Nie otrzymuję przyczyny tego błędu. Dziękujemy za pomoc

Odpowiedz

7

Myślę, że już zostało wyjaśnione, że this.name = Name w ustawieniu wywołuje ponownie settera, co prowadzi do nieskończonej rekurencji.

Jak o tym aproach:

function Ab(_name){ 
    Object.defineProperty(this, "name", { 
     //enumerable: true, //maybe? 
     get: function(){ return _name }, 
     set: function(value){ _name = value } 
    }); 
} 

var c = new Ab("abcde"); 
console.log(c, c.name); 

Or prototypal-podejściu
Wada: własności prywatnej _name jest publiczną

function Ab(n){ 
    this.name = n; 
} 
Object.defineProperty(Ab.prototype, "name", { 
    get: function(){ return this._name }, 
    set: function(value){ this._name = value } 
}); 

Albo ES6
niemal tak samo jak prototypowe zgłoszenie

class Ab{ 
    constructor(n){ 
     this.name = n; 
    } 

    get name(){ return this._name }, 
    set name(value){ this._name = value } 
} 
+0

drugie i trzecie podejście sprawdziło się najlepiej w moim przypadku, dzięki za odpowiedź! – trickpatty

+0

To -> "prowadzi do nieskończonej rekursji". Upewnij się, że Twój wynik to coś więcej niż "return this.myprop", np. "return" MyProp: "+ this.myprop" – AKMorris

2

Ustawiona składnia wiąże właściwość obiektu z funkcją, która będzie wywoływana, gdy nastąpi próba ustawienia tej właściwości.

Nie musisz wykonywać this.name = Name; wewnątrz funkcji zestawu. Powoduje to rekursywne wywołanie setera powodującego przepełnienie stosu. W rzeczywistości w tym przypadku nie potrzebujesz zupełnie setera. Użyj settera tylko wtedy, gdy musisz wykonać dodatkową pracę, gdy właściwość jest ustawiona lub zmodyfikowana.

More

0

Użyłeś Object.defineProperty() złego. W takim przypadku należy go wywołać niezainicjowanym Object, ab.

Object.defineProperty(ab, 'name', { //.. }; 
+1

Kod jest prawidłowy. Chodzi o to, że ustawia zmienną w seter, ponownie uruchamiając setera. –

1

Ty nazywając swoją własność (name) Tak samo jak pola podkładowej w obiekcie, że jesteś dodając do własności. Dodatkowo, operator this wewnątrz set odnosi się do niewłaściwego zakresu (konkretnie, jest on ograniczony do właściwości, a nie obiektu); z tego powodu rekurencyjnie ustawiasz właściwość name, powodując wyjątek przepełnienia stosu.

można zmodyfikować kod w następujący sposób:

function myObject(n){ 
    this.nameValue = n; 

    Object.defineProperty(this, 'name', { 
     get: function() { 
      return this.nameValue; 
     }, 
     set: function(value) { 
      this.nameValue = value; 
     } 
    }); 
} 

var c = new myObject("foo"); 
console.log(c.name);  //logs "foo" 

c.name="bar"; 
console.log(c.name);  //logs "bar" 

this kluczowe w get i set składników majątku name odnosi się teraz do obiektu funkcji zdefiniowanej przez MyObject, ponieważ Object.defineProperty połączenie jest wewnątrz tej funkcji.

+0

Właśnie tworzysz właściwość akcesora wewnątrz konstruktora. Nie trzeba nawet używać metody defineProperty. –

Powiązane problemy