Methoden in ES6-Objekten: Verwenden von Pfeilfunktionen

90

In ES6 sind beide legal:

var chopper = {
    owner: 'Zed',
    getOwner: function() { return this.owner; }
};

und als Abkürzung:

var chopper = {
    owner: 'Zed',
    getOwner() { return this.owner; }
}

Ist es möglich, auch die neuen Pfeilfunktionen zu verwenden? Beim Versuch so etwas

var chopper = {
    owner: 'John',
    getOwner: () => { return this.owner; }
};

oder

var chopper = {
    owner: 'John',
    getOwner: () => (this.owner)
};

Ich erhalte eine Fehlermeldung, die darauf hinweist, dass die Methode keinen Zugriff auf hat this. Ist dies nur ein Syntaxproblem oder können Sie Fat-Pipe-Methoden nicht in ES6-Objekten verwenden?

Fuchs
quelle
9
Einer der größten Punkte der neuen Funktionssyntax war, dass sie thisanders behandelt wird . Es wird durch die lexikalische Umgebung definiert, in der die Funktion erstellt wurde. Dies bedeutet, dass der thisWert, in dem Sie die chopperVariable erstellen, der thisWert der Funktion ist. Mit anderen Worten, es wird nicht auf das chopperObjekt verwiesen .
1
Während Sie die Fat-Arrow-Syntax verwenden? Nur wenn Sie den thisWert ändern , indem Sie zuerst das chopperObjekt erstellen und dann die Zuweisung in einer Funktion thisausführen, die auf dieses Objekt verweist. Dies kann mit einer Konstruktorfunktion ziemlich sauber erreicht werden.
1
Diese Demo wird in Firefox ausgeführt. Chrome hat es noch nicht. jsfiddle.net/bfyarxfe
2
@fox, du musst 'use strict' für diese jsfiddle verwenden.
Walter Chapilliquen - wZVanG
1
@fox: Es funktioniert gut in einer unterstützten Umgebung. Firefox hat noch keine vollständige Unterstützung. Versuchen Sie es in Continuum und console.log()dem Ergebnis des Methodenaufrufs. Es klappt.

Antworten:

147

Pfeilfunktionen sind nicht dafür ausgelegt, in jeder Situation lediglich als kürzere Version altmodischer Funktionen verwendet zu werden. Sie sollen die Funktionssyntax nicht durch das functionSchlüsselwort ersetzen . Der häufigste Anwendungsfall für Pfeilfunktionen sind kurze "Lambdas", die nicht neu definiert thiswerden. Diese werden häufig verwendet, wenn eine Funktion als Rückruf an eine Funktion übergeben wird.

Pfeilfunktionen können nicht zum Schreiben von Objektmethoden verwendet werden, da, wie Sie festgestellt haben, Pfeilfunktionen über thisdem lexikalisch einschließenden Kontext liegen und thisder Pfeil innerhalb des Pfeils derjenige ist, der aktuell war, in dem Sie das Objekt definiert haben. Was ist zu sagen:

// Whatever `this` is here...
var chopper = {
    owner: 'Zed',
    getOwner: () => {
        return this.owner;    // ...is what `this` is here.
    }
};

Wenn Sie in Ihrem Fall eine Methode für ein Objekt schreiben möchten, sollten Sie einfach die herkömmliche functionSyntax oder die in ES6 eingeführte Methodensyntax verwenden:

var chopper = {
    owner: 'Zed',
    getOwner: function() {
        return this.owner;
    }
};

// or

var chopper = {
    owner: 'Zed',
    getOwner() {
        return this.owner;
    }
};

(Es gibt kleine Unterschiede zwischen ihnen, aber sie sind nur wichtig, wenn Sie superin verwenden getOwner, was Sie nicht sind, oder wenn Sie getOwnerin ein anderes Objekt kopieren .)

Auf der es6-Mailingliste gab es einige Debatten über eine Änderung der Pfeilfunktionen, die eine ähnliche Syntax haben, aber eine eigene this. Dieser Vorschlag wurde jedoch schlecht aufgenommen, da es sich lediglich um Syntaxzucker handelt, der es den Benutzern ermöglicht, die Eingabe einiger Zeichen zu speichern, und keine neue Funktionalität gegenüber der vorhandenen Funktionssyntax bietet. Siehe das Thema ungebundene Pfeilfunktionen .

TJ Crowder
quelle
Wenn ich das richtig lese, scheint es darauf hinzudeuten, dass die Mailingliste syntaktischen Zucker depriorisiert, selbst wenn dies zu einer größeren Einheitlichkeit / Lesbarkeit des Codes führen würde. Derzeit ist es viel schwieriger, die Fettpfeilfunktionen in einem OOP-Kontext unter ES6 zu verwenden, als beispielsweise unter Coffeescript.
Fuchs
Wie ich es verstehe, syntaktischer Zucker ist ein triftiger Grund für die Annahme , Spracherweiterungen, sondern als Sie mit einer niedrigeren Priorität sagen - mit anderen Worten, die Bar ist für solche Vorschläge höher.
10

In dieser Zeile getOwner: => (this.owner)sollte stehen:

var chopper = {
    owner: 'John',
    getOwner: () => this.owner
}; //here `this` refers to `window` object.

Sie müssten thisin eine Funktion deklarieren :

var chopper = {
    owner: 'John',
    getOwner() { return this.owner }
};

Oder:

var chopperFn = function(){

    this.setOwner = (name) => this.owner = name;
    Object.assign(this,{
        owner: 'Jhon',
        getOwner: () => this.owner,
    })

}

var chopper = new chopperFn();
console.log(chopper.getOwner());
chopper.setOwner('Spiderman');
console.log(chopper.getOwner());

Walter Chapilliquen - wZVanG
quelle
1
Ich erhalte hier eine Fehlermeldung:"TypeError: Cannot read property 'owner' of undefined\n at Object.chopper.getOwner
Fuchs
Ich sehe, es ist die richtige Verwendung, aber die Methode esta gibt immer Fensterobjekt zurück. Sie müssten thisinnerhalb einer Funktion deklarieren .
Walter Chapilliquen - wZVanG
2
thisbezieht sich nicht unbedingt auf window. Es bezieht sich auf den aktuellen Wert von thisin der umgebenden Umgebung, der möglicherweise vorhanden ist oder nicht window. Vielleicht hast du das gemeint. Ich möchte nur sicherstellen, dass er versteht, dass es sich nicht um einen Standardwert handelt.
@torazaburo Das ist in Ordnung für mich, ich habe es versucht, thisbezieht sich jetzt auf Klasse
Walter Chapilliquen - wZVanG
2
Was Sie geschrieben haben, ist äquivalent, aber ausführlicher als nur zu schreiben var chopperFn = function() { this.owner = 'Jhon'; this.getOwner = () => this.owner; }.
1

Ein kurzer Tipp, den ich befolge, um Pfeilfunktionen zu verwenden.

  • Verwenden Sie Nicht-Pfeil-Funktionen für Methoden, die object.method()Syntax verwenden. (Dies sind Funktionen, die thisvon ihrem Anrufer einen aussagekräftigen Wert erhalten .)
  • Verwenden Sie die Pfeilfunktion für fast alles andere.
Isuru Maldeniya
quelle
0

Wenn Sie mit dem Pfeil Funktion haben, können Sie ändern thiszu chopper,

var chopper = {
  owner: "John",
  getOwner: () => chopper.owner
};

Obwohl dies keine bewährte Methode ist, müssen Sie beim Ändern des Objektnamens diese Pfeilfunktion ändern.

Foxiris
quelle