jobo: "__proto__" nachbauen

Hallo,

wie kann ein bereits existierendes Objekt von einem anderen erben bzw. dieses in seine Prototypenkette mit einhängen? Ich finde Mozillas __proto__, das macht das so:

  
var myObject = {  
	textIndivid : "myIndividualText",  
	textAll : "objtext",  
	fun : function () {  
		alert(this.textIndivid);  
	}  
};  
var myExtObject = {  
	textIndivid : "extIndividText"  
};  
myExtObject.__proto__ = myObject;  
myExtObject.fun();//"extIndividText"  
alert(myExtObject.textAll);//"objtext"  

Wie kan ich das aber machen, ohne das proprietäre "__proto__"?

Nur mit einer Funktion wie dieser?

  
function extend(child, parent){  
	for (property in parent.prototype) {  
	    if (typeof child.prototype[property] == "undefined") {  
		 	child.prototype[property] = parent.prototype[property];  
		}  
	}  
	return child;  
}  

Oder indem ich die o.g. Objekte erstmal als Funktionen definiere, dann den prototype der erbenden Funktion auf new ParentFunc(); setzte und mit new ChildClass(); ein Objekt erzeuge? Ich wollte irgendwie gerne auf des "new" verzichten bzw. schauen, wie es mit Objektliteralen geht.

Gruß

jobo

  1. Hallo,

    naja, dazu muss man wohl die drei magischen Properties verstehen, um das Prinzip zu verstehen.

    Wie auch diese schöne Grafik.

    __proto__ macht wohl Sinn, wenn der aktuelle Status eines Objektes mit aufgenommen werden soll, constructorChild.prototype = new Parent();, wenn nicht.

    Gruß

    jobo

    1. Hallo,

      im YUI wäre wohl Y.augment() [(pseudo-)klassische Vererbung] wie wie hier u.a. beschrieben das, was ich mich fragte, wie man das umsetzt. In einer Funktion gleich die neuen Objekteigenschaften mitgeben. Obwohl Crockford ja sein "Objekte erben von Objekten" empfiehlt, wie es in der nächsten ECMA-Spezifikation wohl auch enthalten sein wird (prototypische Vererbung).

        
      var Papa = {vorname: "Papa", nachname:"Müller"}  
      var Kind = Object.create(Papa);  
      Kind.vorname = "Keule"; //Müller bleibt (;-)  
      
      

      Immerhin kein "new" vorhanden.

      Gruß

      jobo

  2. Wie kan ich das aber machen, ohne das proprietäre "__proto__"?

    Nicht. (Nicht in der Reihenfolge.) Es gibt keine standardisierte Möglichkeit, um den Prototyp nachträglich zu überschreiben.

    function extend(child, parent){
    for (property in parent.prototype) {
        if (typeof child.prototype[property] == "undefined") {
    child.prototype[property] = parent.prototype[property];
    }
    }
    return child;
    }

      
    Du verwechselst hier anscheinend etwas.  
      
    Es gibt \_\_proto\_\_ (intern [[Prototype]]) und prototype. Letztere haben nur Funktionen und damit lässt sich der Prototyp (also \_\_proto\_\_/[[Prototype]]) von Objekten setzen, die mit new mithilfe diese Funktion erzeugt werden.  
      
    Die obige Helferfunktion mixt die Member eines Konstruktor-Prototyps in einen anderen hinein. Das geht, ist dann aber keine prototypische Delegation zwischen child und parent, sondern einfach ein Kopieren der Member.  
      
    Sie mixt nicht die Member eines Prototyps eines beliebigen Objektes in einen anderen Objekt-Prototyp ein. Das geht nur, wenn man Zugriff auf die Prototyp-Kette hat. Das ginge natürlich \_\_proto\_\_ oder Object.getPrototypeOf() aus ES5.  
      
    
    > Oder indem ich die o.g. Objekte erstmal als Funktionen definiere, dann den prototype der erbenden Funktion auf new ParentFunc(); setzte und mit new ChildClass(); ein Objekt erzeuge?  
      
    Ich verstehe den Satz nicht. Natürlich kannst du folgendes schreiben:  
      
    ~~~javascript
    var myObject = {  
            textIndivid : "myIndividualText",  
            textAll : "objtext",  
            fun : function () {  
                    alert(this.textIndivid);  
            }  
    };  
    function f(){}  
    f.prototype = myObject;  
    var myExtObject = new f;  
    myExtObject.textIndivid = "extIndividText";  
    myExtObject.fun();//"extIndividText"  
    alert(myExtObject.textAll);//"objtext"
    

    Dieser Schritt ist ja genau der, den Object.create wegkapselt.

    Ich wollte irgendwie gerne auf des "new" verzichten bzw. schauen, wie es mit Objektliteralen geht.

    Mit Object.create, aber wie gesagt nicht in der Reihenfolge.

    Noch ein Link dazu: Object-Based Inheritance For ECMAScript 5

    Mathias