2013-06-17 9 views
9

Czy ktoś może mi wyjaśnić, dlaczego ten prosty fragment kodu nie działa?Jak korzystać z pobierających i ustawiających w JavaScript

var user = { 
    get name() { 
     return this.name; 
    },  
    set name(value) { 
     this.name = value; 
    } 
}; 
user.name = 'David'; 

Kiedy kładę to w konsoli Firebug Firefox 21,0 daje mi ten błąd:

InternalError: too much recursion 
this.name = value; 

Dlaczego? Jaki jest właściwy sposób definiowania modułów pobierających i ustawiających w JavaScript?

+0

Rekursywnie wywołujesz name() ad infinitum, stąd błąd "zbyt duża rekursja" – stackErr

+1

Problem polega na tym, że próbujesz ustawić właściwość o nazwie "name" w swoim ustawiaczu. Co to zrobi? Będzie wywoływał program ustawiający, który spróbuje ustawić właściwość o nazwie "nazwa". Co to zrobi? ... – Pointy

+2

Problem polega na tym, że 'this.name = value;' wyzwala funkcję 'set name (value)' która ustawia 'this.name = value;', która wyzwala funkcję 'set name (value)' .. Mogę iść dalej. –

Odpowiedz

13

Podczas próby ustawienia name, funkcja ustawi się na this.name = value.

Ale funkcja próbuje teraz ustawić name. Dlatego wywoła funkcję ponownie i ustawi this.name na value.

Ale funkcja próbuje teraz ustawić name. Dlatego wywoła funkcję ponownie i ustawi this.name na value.

Ale funkcja próbuje teraz ustawić name. Dlatego wywoła funkcję ponownie i ustawi this.name na value.

....... Jakiś czas później .......

Ale ta funkcja jest teraz próbuje ustawić name. Dlatego wywoła funkcję ponownie i ustawi this.name na value.

Jednak przeglądarka ustaliła, że ​​stos wywołań jest zbyt głęboki, funkcja nazywa się zbyt wiele razy i dlatego, aby zapobiec całkowitemu zawieszeniu, powoduje awarię funkcji z powodu błędu, który widzisz.


Spróbuj użyć innej nazwy właściwości, na przykład this._name, aby zapisać i pobrać wartość.

+0

Musisz kochać rekursję. Dzięki Bogu, to nie jest możliwe w Lua. W przeciwnym razie miałbyś nieskończoną pętlę, która nigdy nie spowodowałaby błędu. Optymalizacja wywołania ogona FTW. –

+0

Nazywam to Vicious Möbius Strip. To jest jak błędne koło, ale ma tylko jedną stronę;) –

+0

To bardziej przypomina błędne toroidalne pole. Wychodzisz z jednej strony i kończysz po drugiej stronie i robisz to, aż w końcu zdasz sobie sprawę, że biegasz w kółko i poddajesz się. –

4

spróbować

var user = { 
    get name() { 
     return this._name; 
    },  
    set name(value) { 
     this._name = value; 
    } 
}; 
user.name = 'David'; 

Uwaga wykorzystanie _name zamiast name. Ustawienie wartości name w ustawieniu name jest wywołaniem rekurencyjnym, stąd wyjątek.

13

Twój seter sam siebie nazywa.

Oto rozwiązanie:

var user = { 
    get name() { 
     return this._name; 
    },  
    set name(value) { 
     this._name = value; 
    } 
}; 
user.name = 'David'; 

Side Uwaga: Należy uważać, aby operatorzy get i set nie są obsługiwane w IE8.

+1

Dla [odnośnik] (https: //developer.mozilla .org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects? redirectlocale = en-US i redirectslug = JavaScript% 2FGuide% 2FWorking_with_Objects # Defining_getters_and_setters) ... –

Powiązane problemy