it-swarm.com.de

ES6 - deklarieren Sie eine Prototypmethode für eine Klasse mit einer Importanweisung

Ich verwende ES6-Klassen. Ich möchte das können:

function Car(color) {
  this.color = color;
};

Car.prototype.getColor = require('./getColor');

Wo Farbe erhalten ist eine exportierte Funktion. Das heißt, ich möchte in der Lage sein, eine Funktion aus einer externen Datei zu importieren und als Prototypmethode in der ES6-Klasse festzulegen. Über diese Art von Syntax spreche ich:

class Car {
  constructor(color) {
    this.color = color;
  }

  getColor() {} // I want to import this function from './getColor', as above
}

Ist das machbar?

25

Sie können immer noch eine Methode an einen class 'Prototyp anhängen. Klassen sind schließlich nur syntaktischer Zucker über einem "funktionalen Objekt", das ist die alte Art, eine Funktion zum Konstruieren von Objekten zu verwenden.

Da Sie ES6 verwenden möchten, verwende ich einen ES6-Import.

Minimaler Aufwand unter Verwendung des Prototyps:

import getColor from 'path/to/module';

class Car {
    ...
}

Car.prototype.getColor = getColor;

Wie Sie sehen, verwenden Sie immer noch die prototype -Eigenschaft zum Anhängen einer Methode, falls Sie dies wünschen.


Aufruf des Moduls innerhalb einer Klassenmethode:

Wenn Sie die prototype -Eigenschaft nicht verwenden möchten, können Sie die Funktion auch immer aus dem Modul zurückgeben lassen:

import getColor from 'path/to/module';

class Car {
    getColor () {
        return getColor.call(this);
    }
}

Getter verwenden

Sie könnten auch etwas kniffelig sein und einen "Getter" verwenden, um dies auf andere Weise zu erreichen.

import getColor from 'path/to/module';

class Car {
    get getColor () { return getColor.bind(this) }
}

Sie können es dann einfach verwenden, indem Sie myInstanceOfCar.getColor() aufrufen.

Oder in einer semantischeren Verwendung eines Getters:

class Car {
    get color () { return getColor.call(this) }
}

// ...

const color = myInstanceOfCar.color;

Beachten Sie, dass Getter/Setter nicht denselben Namen haben dürfen wie Eigenschaften, die Sie im Konstruktor festlegen. Wenn Sie versuchen, den Setter zu verwenden, um dieselbe Eigenschaft festzulegen, wird der maximale Aufrufstapel mit unendlicher Rekursion überschritten. Beispiel: set foo (value) { this.foo = value }


ES2016-Klasseneigenschaften

Wenn Sie verwenden, um Babel zu transpilieren (und experimentelle Vorschläge verwenden) und ES2016 verwenden möchten, können Sie die folgende Syntax verwenden (beachten Sie jedoch, dass dies die Methode direkt auf das Objekt und setzt es nicht auf den Prototyp):

import getColor from 'path/to/module';

class Car {
    getColor = getColor;
}

Optionale Eigenschaften der Bindung mit Klassen

Wenn Sie zum Festlegen einer Eigenschaft die Abkürzungssyntax verwenden, müssen Sie Sie müssen die Methode nicht binden (Einstellung ändert sich, wenn sich eine Eigenschaft ändert, auf die sich "this" bezieht und im Wesentlichen automatisch bindet) Sie entscheiden sich dafür (wie wenn Sie etwas anderes binden möchten):

getColor = getColor.bind(this);
28
ndugger

Ja. Die class-Syntax ist nur (sehr ausgefeilter) syntaktischer Zucker für Konstruktorfunktionen. Car ist also immer noch eine Funktion mit einer prototype-Eigenschaft, und Sie können genau das gleiche tun:

import getColor from './getColor';
// ...
Car.prototype.getColor = getColor;

Das macht die Methode jedoch im Gegensatz zu den Methoden, die mit der Klassensyntax erstellt wurden, zahlreich. Möglicherweise möchten Sie stattdessen Object.defineProperty verwenden.

3
Felix Kling

Wenn Sie interessiert sind, habe ich ein kleines Modul entwickelt, um Funktionen mit einer Vielzahl von Parametern an Klassenmethoden zu binden: https://github.com/ngryman/to-method .

const toMethod = require('to-method');

function Car(color) {
  this.color = color;
}

toMethod(Cat, { getColor: require('./getColor') });
0
ngryman