[OOP] Von Prototype-Objekt auf Kindobjekt zugreifen

Parantatatam

mag Cookies & Kekse
Hallo Tutorianer,

seit langer Zeit habe ich mal wieder ein Problem, was ich anscheinend nicht selber lösen kann. Allerdings beschäftige ich mich erstmals mit der Prototypen-Architektur von Javascript und bin dabei auf ein Problem gestoßen: wenn ich nun beispielsweise einen Prototypen für das HTMLElement erstelle um somit dann auf dieses bestimmte eigene Methoden anwenden zu können. Dabei würde ich gerne auf die Methoden des eigentlichen HTML-Elements zugreifen können. Leider weiß ich nicht ganz wie.
Code:
HTMLElement.prototype.model = {
  set data(value) {
    this._data = value;
  },
  
  add: function (element) {
    this._elements = element;
  },

  getContent: function () {
    return this.innerHTML; // Verweis auf HTMLElement?
  }
};
Als Beispiel habe ich jetzt mal die Methode getContent() eingefügt. Wie kann ich jetzt auf das entsprechende Objekt zugreifen?
 
Das mit dem Garnicht glaube ich nicht. Aber zu deinem Einwand, dass ich mich nicht zu sehr darin vertiefen sollte, da es generell eine schlechte Idee ist das DOM zu erweitern: Beim dem, was ich vor habe, wäre es viel zu aufwendig ein eigenes Framework zu schreiben. Außerdem werden darin Funktionen verwendet, die so oder so erst mit HTML5 erscheinen, womit IE < 8 und Safari 2.x und ähnliches so oder so weg sind.

Was ich allerdings interessant fand, war das hier, wo es anscheinend doch möglich ist auf die Werte des Kindes zurück zu greifen:
Code:
Element.prototype.hide = function() {
    this.style.display = 'none';
};
...
var element = document.createElement('p');

element.style.display; // ''
element.hide();
element.style.display; // 'none'
 
Was ich allerdings interessant fand, war das hier, wo es anscheinend doch möglich ist auf die Werte des Kindes zurück zu greifen:

Du versuchst aber nicht auf das Kind zuzugreifen, sondern du müsstest erst mal eine Ebene höher, was unmöglich ist. Dein "model" ist ein komplett eigenständiges Objekt. Dieses weiß nichts davon, dass ein anderen Objekt darauf eine Referenz hat.

Und das was du da interessant fandes, ist doch genau das, was wollmaus gesagt hat (siehe code!).
 
Das mit dem hide() da ist dasselbe wie in meiner Antwort, wie CPoly schon sagte:
Code:
HTMLElement.prototype.getContent=function(){/**/}

In deinem Eingangsposting jedoch sieht es so aus:
Code:
HTMLElement.prototype.model.getContent=function(){/**/}
Damit erweiterst du nicht den prototype von HTMLElement um eine Funktion getContent, sondern weist dem prototype von HTMLElement einen member "model" zu. Der Konstruktor von model ist [Object] und nicht [HTMLElement], daher kein Zugriff auf das Element.


Was theoretisch ginge wäre die Nutzung von __defineGetter__

Beispiel: (Erweiterung um Methode swapNode(), welche momentan nur der IE kennt)
Code:
HTMLElement.prototype.__defineGetter__("model", function() { return this });
HTMLElement.prototype.model.swapNode=function(e)
{
  if(this.hasOwnProperty('swapNode') && typeof this.swapNode=='function')
  {
     return this.swapNode(e);                                         
  }
  else
  {
    var tmp=document.createTextNode('');
        e.parentNode.insertBefore(tmp,e);
        this.parentNode.insertBefore(e,this);
        tmp.parentNode.insertBefore(this,tmp);
        tmp.parentNode.removeChild(tmp);
        return this;
  }
  
};
Wermutstropfen dabei: IE unterstützt __defineGetter__ bisher noch nicht :D

Demo: http://jsfiddle.net/dM4qR/ (Sollte in aktuellen FF und Chrome laufen)
 
Zuletzt bearbeitet:
Ich danke euch beiden erstmal, da eure Ansätze mir genug Stoff für eigene Inspiration geliefert haben. Dabei habe ich übrigens herausgefunden, dass die Methoden __defineGetter__ und __defineSetter__ in der neusten Version von Javascript als veraltet gelten. Sie wird demnächst durch die Methode Object.defineProperty ersetzt, welche auch vom Internet Explorer 8 unterstützt wird. Diese Methode bietet wesentlich mehr Möglichkeiten, womit eigene Methoden annähernd gleichzusetzen sind mit denen aus dem nativen Javascript-Code.

Hier aber auch noch das Ergebnis, zu welchem ich gekommen bin (ich verwende erstmal nur __defineGetter__, da das für mich ausreichend ist und von Chrome auch unterstützt wird):
Code:
HTMLElement.prototype.__defineGetter__("model", function () {
  if(this.__model__ == undefined) {
    this.__model__ = new Model(this);
  }
  
  return this.__model__;
});

function Model(obj) {
  this._element = obj;
}

Model.prototype = {
  set data(values) {
    this._data = values;
  },
  
  add: function (element) {
    
  },
  
  output: function() {
    var output = "";
    for(var line in this._data) {
      output = output + " | " + (typeof line);
    }
    
    console.log(output);
  }
}

document.getElementById("example").model.data = [1, 2, 3, 4];
document.getElementById("example").model.output();
Es soll aber anscheinend auch noch eine Möglichkeit geben, die ich allerdings im Chrome nicht zum Laufen bekommen habe:
Code:
HTMLElement.prototype = {
  get model() {
    if(this.__model__ == undefined) {
      this.__model__ = new Model(this);
    }
    return this.__model__;
  }
}
 

Neue Beiträge

Zurück