5

Próbuję uzyskać obiekt JavaScript, aby użyć "tego" przypisania konstruktora innego obiektu, a także założyć prototyp wszystkich tych obiektów Funkcje. Oto przykład tego, co ja próbuje osiągnąć:Funkcja JavaScript używająca "this =" daje "Nieprawidłowa lewa strona w przypisaniu"

/* The base - contains assignments to 'this', and prototype functions 
    */ 
function ObjX(a,b) { 
    this.$a = a; 
    this.$b = b; 
} 

ObjX.prototype.getB() { 
    return this.$b; 
} 

function ObjY(a,b,c) { 
    // here's what I'm thinking should work: 
    this = ObjX(a, b * 12); 
    /* and by 'work' I mean ObjY should have the following properties: 
    * ObjY.$a == a, ObjY.$b == b * 12, 
    * and ObjY.getB == ObjX.prototype.getB 
    * ... unfortunately I get the error: 
    *  Uncaught ReferenceError: Invalid left-hand side in assignment 
    */ 

    this.$c = c; // just to further distinguish ObjY from ObjX. 
} 

Byłbym wdzięczny za swoje myśli, w jaki sposób mają ObjY podciągnięcia przypisania ObjX do „tego” (nie znaczy trzeba powtórzyć wszystkie this.$* = * zadania w Konstruktor ObjY) i niech ObjY przyjmie ObjX.prototype.

Moja pierwsza myśl to spróbuj wykonać następujące czynności:

function ObjY(a,b,c) { 
    this.prototype = new ObjX(a,b*12); 
} 

Idealnie chciałabym dowiedzieć się, jak to zrobić w sposób prototypal (czyli nie trzeba używać żadnej z tych „klasycznych” jak substytuty OOP Base2).

Warto zauważyć, że ObjY będzie anonimowy (na przykład factory['ObjX'] = function(a,b,c) { this = ObjX(a,b*12); ... }) - jeśli mam właściwą terminologię.

Dziękuję.

+1

related: [? Dlaczego nie można przypisać nową wartość „to” w funkcji prototypowej] (http: // stackoverflow.com/q/9713323/1048572) – Bergi

Odpowiedz

15

Tak naprawdę nie można tego zrobić, ponieważ wartość this z definicji jest niezmienna, nie można zmienić w ten sposób, do czego się odnosi.

Rozwiązaniem byłoby użyć call lub apply metod, aby uruchomić funkcję ObjX konstruktora w this przedmiotu ObjY:

function ObjY(a,b,c) { 
    ObjX.call(this, a, b * 12); 
    this.$c = c; 
} 

W powyższym przykładzie funkcja ObjX jest wykonywany zmienia swoją wartość this, więc wszystkie rozszerzenia właściwości, które wprowadzisz do tego obiektu w tej funkcji, zostaną odzwierciedlone w nowym obiekcie, do którego odnosi się wartość this w konstruktorze ObjY.

Po zakończeniu metody call obiekt this zostanie powiększony i będzie można uzyskać więcej rozszerzeń właściwości, np. Dodając wartość $c.

Edit: O prototypach, próbka nie będzie działać, ponieważ nieruchomość prototype ma szczególne znaczenie dla obiektu w postaw będzie tak jak każdej innej własności, powinno ono być stosowane na funkcji konstruktora.

Myślę, że możesz pomylić właściwość prototype konstruktorów z wewnętrzną właściwością [[Prototype]], którą posiadają wszystkie obiekty.

Obiekt [[Prototype]] mogą być ustawione tylko przez operatora new (poprzez działania wewnętrznego [[Construct]]), właściwość ta nie może być zmieniony, (choć niektóre implementacje, jak ten Mozilla, można uzyskać do niego dostęp za pośrednictwem obj.__proto__;, aw Wprowadzono ECMAScript 5, wprowadzono metodę Object.getPrototypeOf, ale nie poleciłbym, abyś zadzwonił bezpośrednio z nią).

Faktycznie, gdy konstruktor jest wykonywany wewnętrzny [[Prototype]] właściwość obiektu, że wartość this dotyczy, został już ustawiony do jego konstruktora prototype nieruchomości.

Tak, jak @Anurag komentarzach, można ustawić ObjY.prototype do nowo utworzonej ObjX obiektu:

function ObjY(a,b,c) { 
    ObjX.call(this, a, b * 12); 
    this.$c = c; 
} 

ObjY.prototype = new ObjX(); 
ObjY.prototype.constructor = ObjY; 

które uczynią że ObjY dziedziczą również właściwości dodawane do ObjX.prototype, i jak widać, Zmieniłem ObjY.prototype.constructor, ponieważ przypisanie w powyższym wierszu spowoduje, że ta właściwość będzie niepoprawnie wskazywać na ObjX.

Polecane artykuły:

+1

Dziękuję CMS. Świetny link też. Drugie pytanie brzmi: jak przypisać prototypy - czy można to zrobić z poziomu konstruktora? –

+0

@Brian, nie ma za co, tak, miałem literówkę! – CMS

+0

@ Brian, ustaw obiekt ObjX jako prototyp dla ObjY, aby uzyskać również jego metody. 'ObjY.prototype = new ObjX;'. Metody i właściwości, jeśli nie zostały znalezione w bieżącym obiekcie, są wyszukiwane w łańcuchu prototypów. – Anurag

Powiązane problemy