2016-06-02 12 views
-2

aufrufen Sagen wir haben eine Konstruktorfunktion in JavaScript, die ich verwenden, um meine Objekte zu erstellen. Wie würde ich den "Inhalt" aller Objekte ändern, die von dieser Funktion durch einen Methodenaufruf von dieser Funktion erstellt werden. Ich frage mich, ob es möglich ist, einen Methodenaufruf auf den Prototyp aufzurufen, so wie wir den Prototyp modifizieren und unsere eigenen Methoden/Eigenschaften hinzufügen würden.Ist es möglich, eine Methode aus einer Objektdefinition Konstruktor Funktion

Zum Beispiel:

function MyConstructor() 
{ 
    var privateVariable = "This is an ORIGINAL private variable"; 
    this.publicVariable = "This is public"; 

    this.modificationMethod = function(){ 
    // I want to call this methode on the prototype 
    privateVariable = "I am now changed"; 
    }; 

    this.alertMe = function(){ 
     alert(privateVariable); 
    }; 
} 

var a = new MyConstructor(); 
a.alertMe();  // alerts This is an ORIGINAL private variable 
a.modificationMethod(); 
a.alertMe();  // alerts I am now changed 

Dies funktioniert, wenn ich ein einzelnes Objekt zu ändern, ich die Methode aufrufen, ändert es das einzelne Objekt. Ich möchte jedoch alle Objekte ändern, die vom Konstruktor erstellt werden.

Ich weiß, dass ich neue Methoden, um es wie folgt hinzufügen:

MyConstructor.prototype.foo = function(){ 
    alert("foo"); 
} 
a = new MyConstructor(); 
a.foo(); 

Aber es lässt mich nicht die bestehenden Methoden ausführen, um die Eigenschaften zu ändern, und wirft einen Fehler:

MyConstructor.prototype.modificationMethod(); 

"modificationMethod ist keine Funktion"

+0

'MyConstructor.prototype.foo = function() {this.modificationMethod()}; a = neu MyConstructor(); ein.foo() ' –

+0

Dies löst das Problem nicht wirklich, es macht eine andere Methode, die die erste Methode aufrufen wird, aber sie ruft sie nie auf. Es erstellt nur eine Methode, um eine Methode aufzurufen, während ich die Methode ausführen muss, um eine private Eigenschaft für alle Objekte zu ändern, muss die Methode auf dem Prototyp aufgerufen werden, nicht eine Instanz von eins ('a'). – Dellirium

+0

Sie können keine privaten Eigenschaften von 'prototype' abrufen, da private Eigenschaften nur innerhalb von 'function constructor scope' existieren. –

Antwort

1

BEARBEITEN: Aktualisieren der Antwort, um alles widerzuspiegeln in Kommentaren gequält. Ich habe das Problem des OP zunächst falsch verstanden.


Jedes Objekt ist mit einem Prototyp-Objekt verknüpft. Beim Versuch, auf eine Eigenschaft zuzugreifen, die nicht existiert, sucht JavaScript im Prototypobjekt des Objekts nach dieser Eigenschaft und gibt es zurück, wenn es existiert.

Die Prototypeigenschaft eines Funktionskonstruktors bezieht sich auf das Prototypobjekt aller Instanzen, die mit dieser Funktion erstellt wurden, wenn new verwendet wird.

Was das bedeutet ist, dass Prototyp-Objekt eine Art Fallback-Mechanismus ist, wenn ein Objekt selbst nicht die gewünschte Eigenschaft hat.


Das Konzept der privaten Variablen sind in der Tat closures.

Prototyp-Funktionen sind außerhalb des Konstruktorfunktionsbereichs definiert, dh sie können nicht auf die "privaten Eigenschaften" zugreifen.

Es ist jedoch möglich, der Prototypeigenschaft selbst eine Schließung zuzuweisen, wodurch effektiv eine private gemeinsame (statische) Variable erstellt wird.

function MyConstructor() {}; 

MyConstructor.prototype = (function() { 

    var extensions = { 
    foo: null, 
    test: function() { 
     alert("Test was extended"); 
    } 
    }; 

    return { 
    registerExtension: function(name, callback) { 
     extensions[name] = callback; 
    }, 
    // in order to use the extensions object, you need a generic function such as invoke 
    invoke: function(name) { 
     if (typeof extensions[name] === 'function') 
     extensions[name].call(this); 
    } 
    }; 

}()); 

var a = new MyConstructor(); 
a.invoke('test'); //will alert 
a.invoke('foo'); //will not alert (not a function) 
a.registerExtension('foo', function() { 
    alert("foo is now extended as well"); 
}); 
a.invoke('test'); //will alert 
a.invoke('foo'); //will alert 

Ein einfacher Ansatz, wenn Sie für die erweiterten Funktionen nichts dagegen sichtbar (öffentlich) zu sein, wäre direkt die prototype erstrecken.

function MyConstructor() {}; 

MyConstructor.prototype = { 
    foo: null, 
    test: function() { 
    alert("Test was extended"); 
    } 
}; 

var a = new MyConstructor(); 
a.test(); //will alert 
//a.foo(); //will not alert (not a function) 
MyConstructor.prototype.foo = function() { 
    alert("foo is now extended as well"); 
}; 
a = new MyConstructor(); 
a.test(); //will alert 
a.foo(); //will alert 

Sie können problemlos eine Schnittstelle für die Erweiterung des Prototyps erstellen.

Object.prototype.registerExtension = function(name, func){ 
    this.prototype[ name ] = func; 
}; 

// ... 

MyConstructor.registerExtension('foo', function() { 
    alert("foo is now extended as well"); 
}); 
+0

Ich verstehe diese Konzepte, aber Sie haben es entweder falsch formuliert oder wir haben kein klares Verständnis. Um Sie zu zitieren: "Wenn Sie jede Instanz ändern möchten, müssen Sie die Funktionen einzeln aufrufen". Dies würde für bestehende Instanzen gelten, was ich tun möchte, ist den Prototyp zu verändern, und jede zukünftige Instanz, die diesen neuen, veränderten Prototyp verwendet, würde dann andere Eigenschaften erhalten. Ich werde in der nächsten Antwort weiter ausführen. – Dellirium

+0

Von dem, was ich verstehe, und, korrigieren Sie mich, wenn ich falsch liege. Wenn ich ein 'neues' Objekt erzeuge, wird dieses Objekt basierend auf dem ** aktuellen Zustand ** des Prototypobjekts der Konstruktorfunktion erstellt. Wenn sich das Prototypobjekt der Konstruktorfunktion irgendwie ändern würde, hätten alle neu erstellten Instanzen dann den neuen Zustand. Das ist im Wesentlichen was ich suche. Jetzt ist es möglich, es zu tun, indem man neue Eigenschaften hinzufügt, die auf Funktionen zum Prototyp beziehen, alle Objekte erben es. Aber es scheint unmöglich, irgendeine Methode auf dem Prototyp aufzurufen, als ob die Methoden gar nicht vorhanden wären. – Dellirium

+0

Müssen Sie private Eigenschaften innerhalb der Prototypfunktionen verwenden? – destoryer

Verwandte Themen