Orlok: mehrere ezeugte Object des selben konstruktors steuern

Beitrag lesen

Hallo

[…] kannst du mir mal erklären was es mit nem parameter "features" und eigenschaft "features.model" auf sich hat und du die verknüpfst???

Zunächst einmal hat Felix hier ein Beispiel für eine Konstruktorfunktion gegeben, welche über einige Eigenschaften und Methoden verfügt, nach dem Schema:

var Constructor = function ( ) {
  this.property = 'value';
  this.method = function ( ) {
    return this.property;
  };
};

Nehmen wir nun an, du erzeugst eine Instanz davon, möchtest aber, dass der Wert der Eigenschaft property dieses neu erstellten Funktionsobjektes ein anderer ist, dann müsstest du hier schreiben:

var instance = new Constructor( );
instance.property = 'otherValue';

Das ist eine Möglichkeit, aber nicht besonders elegant. Besser wäre es, der Konstruktorfunktion einen Parameter mit auf den Weg zu geben:

var Constructor = function (val) {
  this.property = val;
  this.method = function ( ) {
    return this.property;
  };
};

var instance = new Constructor('value');
var val = instance.method( ); // value

Praktikabel wäre diese Lösung aber nicht, denn wenn wir es so schreiben und bei der Erzeugung einer Instanz kein Argument übergeben, dann wird der Parameter val und mithin die Eigenschaft property mit undefined initialisiert, und der Sinn der Übung besteht ja gerade darin, nicht jede Objekteigenschaft separat anlegen zu müssen, sondern sich Schreibarbeit zu sparen, indem man einer Stelle Eigenschaften und Methoden hinterlegt, die dann an mehrere Instanzen vererbt werden.

Das heißt, wir wollen einerseits, dass bestimmte Defaultwerte vorhanden sind, aber andererseits wollen wir auch die Möglichkeit haben, für die jeweiligen Eigenschaften bei der Instanzierung abweichende Werte zu bestimmen. Darum müssen wir in der Konstruktorfunktion prüfen, ob ein Parameter übergeben wurde, und nur in diesem Fall wird der entsprechende Defaultwert überschrieben:

var Constructor = function (val) {
  this.property = 'value';
  if (val) {
    this.property = val;
  }
  this.method = function ( ) {
    return this.property;
  };
};

var first = new Constructor( );
console.log(first.method( )); // value

var second = new Constructor('otherValue');
console.log(second.method( )); // otherValue

Allerdings kann man das auch etwas eleganter formulieren und statt der Prüfung mittels if-Statement folgendes schreiben:

var Constructor = function (val) {
  this.property = val || 'value';
  this.method = function ( ) {
    return this.property;
  };
};

Nehmen wir nun aber einmal an, unsere Konstruktorfunktion hat nicht nur eine Eigenschaft, sondern zehn oder zwanzig, dann würden wir uns hier mit der Parametrisierung einen abbrechen. Daher ist es besser, statt einen Haufen einzelner Werte zu übergeben, diese Werte in einem Objekt zu hinterlegen, welches dann als einziges Argument übergeben wird:

var Constructor = function (object) {
  this.first = 1;
  if (object && object.first) {
    this.first = object.first;
  }
  this.second = 2;
  if (object && object.second) {
    this.second = object.second;
  }
};

var param = {
  first : 'one',
  second : 'two'
};

var instance = new Constructor(param);
console.log(instance.first); // one
console.log(instance.second); // two

Und das ist im Wesentlichen das, was Felix hier gemacht hat, mit dem Unterschied, dass er das an die Konstruktorfunktion übergebene Objekt nicht erst in einer Variable gespeichert, sondern es direkt beim Aufruf des Konstruktors erzeugt hat, also:

var instance = new Constructor({
  first : 'one',
  second: 'two'
});

Davon abgesehen ist der Grund, weshalb hier nicht nur die Eigenschaft sondern auch auf den Parameter selbst geprüft wird, also if (object && object.property) notiert wird, der, dass falls kein Argument übergeben wurde, object mit undefined initialisiert wird, und dann würde die Prüfung der Eigenschaft hier einen type error produzieren.

Aber auch das könnte man anders notieren:

var Constructor = function (object) {
  this.property = object && object.property || 'value';
};

var first = new Constructor( );
console.log(first.property); // value

var second = new Constructor({ property : 'otherValue' });
console.log(second.property); // otherValue

Gruß,

Orlok