dies (Computerprogrammierung) - this (computer programming)

this , self und Me sind Schlüsselwörter, die in einigen Computerprogrammiersprachen verwendet werden , um auf das Objekt, die Klasse oder eine andere Entität zu verweisen, von der der aktuell ausgeführte Code ein Teil ist. Die Entität, auf die durch diese Schlüsselwörter verwiesen wird, hängt somit vom Ausführungskontext ab (z. B. von welchem ​​Objekt seine Methode aufgerufen wird). Verschiedene Programmiersprachen verwenden diese Schlüsselwörter auf leicht unterschiedliche Weise. In Sprachen, in denen ein Schlüsselwort wie "this" obligatorisch ist, ist das Schlüsselwort die einzige Möglichkeit, auf Daten und Methoden zuzugreifen, die im aktuellen Objekt gespeichert sind. Wo optional, können sie Variablen und Funktionen mit demselben Namen eindeutig machen.

Objekt orientierte Programmierung

In vielen objektorientierten Programmiersprachen ist , this(auch selfoder genannt Me) eine Variable, die in Instanzmethoden verwendet wird , um auf das Objekt zu verweisen, an dem sie arbeiten. Die erste OO-Sprache, SIMULA 67 , wird verwendet, thisum explizit auf das lokale Objekt zu verweisen. C++ und davon abgeleitete Sprachen (wie Java , C# , D und PHP ) verwenden im Allgemeinen ebenfalls this. Smalltalk und andere wie Object Pascal , Perl , Python , Ruby , Rust , Objective-C , DataFlex und Swift verwenden self. Visual Basic von Microsoft verwendet Me.

Das Konzept ist in allen Sprachen ähnlich: thisist normalerweise eine unveränderliche Referenz oder ein Zeiger, der auf das aktuelle Objekt verweist; Das aktuelle Objekt ist oft der Code, der als 'Elternteil' der Eigenschaft , Methode , Unterroutine oder Funktion fungiert, die das thisSchlüsselwort enthält . Nachdem ein Objekt richtig konstruiert oder instanziiert wurde, thisist es immer eine gültige Referenz. Einige Sprachen erfordern dies ausdrücklich; andere verwenden lexikalisches Scoping , um es implizit zu verwenden, um Symbole innerhalb ihrer Klasse sichtbar zu machen. Alternativ kann das aktuelle Objekt, auf das verwiesen wird this, ein unabhängiges Codeobjekt sein, das die Funktion oder Methode aufgerufen hat, die das Schlüsselwort enthält this. So etwas passiert beispielsweise, wenn ein an ein HTML-Tag in einer Webseite angehängter JavaScript- Event-Handler eine Funktion aufruft, die das Schlüsselwort enthält, das thisim globalen Bereich außerhalb des Dokumentobjekts gespeichert ist; thisbezieht sich in diesem Zusammenhang auf das Seitenelement innerhalb des Dokumentobjekts, nicht auf das umschließende Fensterobjekt.

In einigen Sprachen, zum Beispiel C++ und Java, ist thisor selfein Schlüsselwort und die Variable existiert automatisch in Instanzmethoden. In anderen, zum Beispiel Python, Rust und Perl 5, ist der erste Parameter einer Instanzmethode eine solche Referenz. Es muss explizit angegeben werden. In Python und Perl muss der Parameter nicht unbedingt benannt werden thisoder self; er kann vom Programmierer wie jeder andere Parameter frei benannt werden. Nach informeller Konvention heißt der erste Parameter einer Instanzmethode in Perl oder Python jedoch self. Rust erfordert den Aufruf des self-Objekts &selfoder self, je nachdem, ob die aufgerufene Funktion den Aufrufer entlehnt bzw. einzieht.

Statische Methoden in C++ oder Java sind nicht mit Instanzen, sondern mit Klassen verknüpft und können daher nicht verwendet werden this, da kein Objekt vorhanden ist. In anderen Sprachen wie Ruby, Smalltalk, Objective-C oder Swift ist die Methode einem Klassenobjekt zugeordnet , das als übergeben wird this, und sie werden Klassenmethoden genannt . Für Klassenmethoden verwendet Python clsfür den Zugriff auf das Klassenobjekt .

Feinheiten und Schwierigkeiten

Wenn lexikalisches Scoping verwendet wird, um abzuleiten this, kann die Verwendung von thisim Code, obwohl nicht illegal, bei einem Wartungsprogrammierer Warnglocken läuten lassen, obwohl es thisin diesem Fall immer noch legitime Verwendungen von gibt, wie z gleichen Namens, oder wenn die Methode eine Referenz auf das aktuelle Objekt, dh auf thissich selbst, zurückgeben möchte .

In einigen Compilern (zum Beispiel GCC ) können Zeiger auf C++-Instanzmethoden mit einem expliziten thisZeigerparameter direkt in einen Zeiger eines anderen Typs umgewandelt werden.

Offene Rekursion

Die Dispatch-Semantik von this, nämlich dass Methodenaufrufe thisdynamisch abgefertigt werden, wird als offene Rekursion bezeichnet und bedeutet, dass diese Methoden von abgeleiteten Klassen oder Objekten überschrieben werden können. Im Gegensatz dazu verwendet die direkte benannte Rekursion oder die anonyme Rekursion einer Funktion geschlossene Rekursion mit früher Bindung. Im folgenden Perl- Code für die Fakultät ist das Token __SUB__beispielsweise ein Verweis auf die aktuelle Funktion:

use feature ":5.16";
sub {
    my $x = shift;
    $x == 0 ? 1 : $x * __SUB__->( $x - 1 );
}

Im Gegensatz dazu bindet in C++ ( thisaus Gründen der Übersichtlichkeit ein explizites , wenn auch nicht notwendig) die thisBindung an das Objekt selbst, aber wenn die Klassenmethode als "virtuell", dh polymorph in der Basis deklariert wurde, wird sie über den dynamischen Dispatch ( späte Bindung ) aufgelöst, so dass abgeleitete Klassen können es überschreiben.

unsigned int factorial(unsigned int n)
{
  if (n == 0)
    return 1;
  else
    return n * this->factorial(n - 1);
}

Dieses Beispiel ist künstlich, da es sich um eine direkte Rekursion handelt, sodass das Überschreiben der factorialMethode diese Funktion überschreiben würde. natürlichere Beispiele sind, wenn eine Methode in einer abgeleiteten Klasse dieselbe Methode in einer Basisklasse aufruft, oder in Fällen von gegenseitiger Rekursion.

Das fragile Basisklassenproblem wurde der offenen Rekursion zugeschrieben, mit dem Vorschlag, dass beim Aufrufen von Methoden thisstandardmäßig geschlossene Rekursion (statischer Dispatch, frühe Bindung) statt offener Rekursion (dynamischer Dispatch, späte Bindung) verwendet wird, nur wenn dies spezifisch ist angefordert; externe Anrufe (ohne this) würden wie gewohnt dynamisch weitergeleitet. In der Praxis wird dies im JDK durch eine bestimmte Programmierdisziplin gelöst; diese Disziplin wurde von C. Ruby und GT Leavens formalisiert; es besteht im Wesentlichen aus den folgenden Regeln:

  • Kein Code ruft publicMethoden auf this.
  • Code, der intern (durch Aufruf von anderen Methoden derselben Klasse) wiederverwendet werden kann, wird in eine protectedoder private-Methode gekapselt ; wenn sie den Benutzern auch direkt zugänglich gemacht werden muss, publicruft eine Wrapper- Methode die interne Methode auf.
  • Für reine Methoden kann die bisherige Empfehlung gelockert werden.

Implementierungen

C++

Frühe Versionen von C++ ließen den thisZeiger ändern; Auf diese Weise konnte ein Programmierer ändern, an welchem ​​Objekt eine Methode arbeitete. Diese Funktion wurde schließlich entfernt und ist jetzt thisin C++ ein r-Wert .

Frühe Versionen von C++ enthielten keine Referenzen, und es wurde vorgeschlagen, dass es sich bei C++ von Anfang thisan um eine Referenz und nicht um einen Zeiger gehandelt hätte.

C++ lässt Objekte mit der Quellcode-Anweisung sich selbst zerstören: delete this.

C#

Das Schlüsselwort thisin C# funktioniert für Referenztypen genauso wie in Java. Jedoch innerhalb von C # Typen Wert , thishat ganz andere Semantik, ähnlich zu sein zu einer gewöhnlichen veränderbaren variable Referenz, und kann auch auf der linken Seite einer Zuweisung auftreten.

Eine Verwendung von thisC# besteht darin, den Verweis auf eine äußere Feldvariable innerhalb einer Methode zuzulassen, die eine lokale Variable mit demselben Namen enthält. In einer solchen Situation weist die Anweisung var n = localAndFieldname;innerhalb der Methode beispielsweise den Typ und den Wert der lokalen Variablen localAndFieldnamezu n, während die Anweisung var n = this.localAndFieldname;den Typ und den Wert der äußeren Feldvariablen zu zuweist n.

D

In D this in einer Klasse bezieht sich die Methode struct oder union auf eine unveränderliche Referenz der Instanz des einschließenden Aggregats. Klassen sind Referenztypen , Strukturen und Unions sind Werttypen. In der ersten Version von D wird das Schlüsselwort thisals Zeiger auf die Instanz des Objekts verwendet, an das die Methode gebunden ist, während es in D2 den Charakter eines impliziten refFunktionsarguments hat.

Dylan

In der Programmiersprache Dylan , die eine objektorientierte Sprache ist, die Multimethoden unterstützt und kein Konzept von hat this, wird das Senden einer Nachricht an ein Objekt immer noch in der Syntax beibehalten. Die beiden folgenden Formulare funktionieren auf die gleiche Weise; die Unterschiede sind nur syntaktischer Zucker .

object.method(param1, param2)

und

method (object, param1, param2)

Eiffel

Innerhalb eines Klassentextes ist der aktuelle Typ der aus der aktuellen Klasse erhaltene Typ . Innerhalb von Features (Routinen, Befehlen und Abfragen) einer Klasse kann man das Schlüsselwort verwenden, Currentum auf die aktuelle Klasse und ihre Features zu verweisen. Die Verwendung des Schlüsselworts Currentist optional, da das Schlüsselwort Currentimpliziert wird, indem einfach offen auf den Namen des aktuellen Klassenmerkmals Bezug genommen wird. Zum Beispiel: Man könnte ein Feature `foo' in einer Klasse MY_CLASS haben und darauf verweisen durch:

  class
     MY_CLASS
  
  feature -- Access
  
     foo: INTEGER
  
     my_function: INTEGER
        do
          Result := foo
       end
 
 end

Zeile 10 (oben) hat den impliziten Verweis auf Currentden Aufruf des einfachen `foo'.

Zeile 10 (unten) hat den expliziten Verweis auf Currentden Aufruf von `Current.foo'.

  class
     MY_CLASS
  
  feature -- Access
  
     foo: INTEGER
  
     my_function: INTEGER
        do
           Result := Current.foo
       end
 
 end

Beide Ansätze sind für den Compiler akzeptabel, aber die implizierte Version (zB x := foo) wird bevorzugt, da sie weniger ausführlich ist.

Wie bei anderen Sprachen gibt es Zeiten, in denen die Verwendung des Schlüsselworts Currentvorgeschrieben ist, wie zum Beispiel:

  class
     MY_CLASS
  
  feature -- Access
  
     my_command
           -- Create MY_OTHER_CLASS with `Current'
        local
           x: MY_OTHER_CLASS
       do
          create x.make_with_something (Current)
       end
 
 end

Im Fall des obigen Codes übergibt der Aufruf von make_with_something in Zeile #11 die aktuelle Klasse, indem explizit das Schlüsselwort übergeben wird Current.

Java

Das Schlüsselwort thisist ein Java- Schlüsselwort, das die aktuelle Instanz der Klasse darstellt, in der es vorkommt. Es wird verwendet, um auf Klassenvariablen und Methoden zuzugreifen.

Da in Java alle Instanzmethoden virtuell sind, thiskann niemals null sein.

JavaScript

In JavaScript, einer Programmier- oder Skriptsprache, die häufig in Webbrowsern verwendet wird, thisist es ein wichtiges Schlüsselwort, obwohl es davon abhängt, wo es verwendet wird.

  • Bei Verwendung außerhalb einer Funktion im globalen Raum thisbezieht sich das Objekt auf das umschließende Objekt, das in diesem Fall das umschließende Browserfenster ist window.
  • Bei Verwendung in einer im globalen Raum definierten Funktion thishängt die Bedeutung des Schlüsselworts davon ab, wie die Funktion aufgerufen wird. Wenn eine solche Funktion direkt aufgerufen wird (zB f(x)), thisverweist auf den globalen Raum, in dem die Funktion definiert ist und in dem auch andere globale Funktionen und Variablen existieren können (oder im strikten Modus ist es undefined). Wenn eine globale Funktion enthaltend thisals Teil des Eventhandlers eines Elements im Dokumentobjekt aufgerufen thiswird , wird jedoch auf das aufrufende HTML-Element verwiesen.
  • Wenn eine Methode mit dem newSchlüsselwort (zB var c = new Thing()) aufgerufen wird, dann thisbezieht sich innerhalb von Thing auf das Thing-Objekt selbst.
  • Wenn eine Funktion als Eigenschaft eines Objekts angehängt und als Methode dieses Objekts aufgerufen wird (zB obj.f(x)), thiswird auf das Objekt verwiesen, in dem die Funktion enthalten ist. Es ist sogar möglich, thisbeim Aufrufen einer Funktion manuell anzugeben , indem Sie die .call()oder .apply()-Methoden des Funktionsobjekts verwenden. Der Methodenaufruf obj.f(x)könnte beispielsweise auch als obj.f.call(obj, x).

Um die unterschiedliche Bedeutung von thisin verschachtelten Funktionen wie DOM-Ereignishandlern zu umgehen, ist es in JavaScript üblich, die thisReferenz des aufrufenden Objekts in einer Variablen (üblicherweise thatoder genannt self) zu speichern und dann die Variable zu verwenden, um auf das aufrufende Objekt zu verweisen Objekt in verschachtelten Funktionen.

Zum Beispiel:

// In this example $ is a reference to the jQuery library 
$(".element").hover(function() {
    // Here, both this and that point to the element under the mouse cursor.
    var that = this;
    
    $(this).find('.elements').each(function() {
        // Here, this points to the DOM element being iterated.
        // However, that still points to the element under the mouse cursor.
        $(this).addClass("highlight");
    });
});

Bemerkenswerterweise verwendet JavaScript beide thisund das zugehörige Schlüsselwort self(im Gegensatz zu den meisten anderen Sprachen, die dazu neigen, das eine oder andere zu verwenden), wobei selfes speziell auf Webarbeiter beschränkt ist.

Schließlich enthält JavaScript das globalThisSchlüsselwort , um zuverlässig auf das globale Objekt (window oder äquivalent) zu verweisen .

Lua

In Lua selfwird als syntaktischer Zucker erzeugt, wenn Funktionen mit dem :Operator definiert werden . Beim Aufrufen einer Methode mit :wird das indizierte Objekt implizit als erstes Argument an die aufgerufene Funktion übergeben.

Die folgenden beiden Funktionen sind beispielsweise äquivalent:

local obj = {}

function obj.foo(arg1, arg2)
  print(arg1, arg2) -- cannot use "self" here
end

function obj:bar(arg)
  print(self, arg) -- "self" is an implicit first argument before arg
end

-- All functions can be invoked both ways, with "." or with ":"

obj:foo("Foo") -- equivalent to obj.foo(obj, "Foo")
obj.bar(obj, "Bar") -- equivalent to obj:bar("Bar")

Lua selbst ist nicht objektorientiert, aber in Kombination mit einem anderen Feature namens Metatabellen ermöglicht die Verwendung von selfProgrammierern die Definition von Funktionen in einer Weise, die der objektorientierten Programmierung ähnelt.

Power Shell

In PowerShell enthält die spezielle automatische Variable $_ das aktuelle Objekt im Pipeline-Objekt. Sie können diese Variable in Befehlen verwenden, die eine Aktion für jedes Objekt oder für ausgewählte Objekte in einer Pipeline ausführen.

"one", "two", "three" | % { write $_ }

Ebenfalls ab PowerShell 5.0, das eine formale Syntax zum Definieren von Klassen und anderen benutzerdefinierten Typen hinzufügt, $thisbeschreibt Variable die aktuelle Instanz des Objekts.

Python

In Python gibt es kein Schlüsselwort für this. Wenn eine Memberfunktion für ein Objekt aufgerufen wird, ruft sie die Memberfunktion mit demselben Namen für das Klassenobjekt des Objekts auf, wobei das Objekt automatisch an das erste Argument der Funktion gebunden wird. Somit dient der obligatorische erste Parameter von Instanzmethoden als this; Dieser Parameter heißt üblicherweise self, kann aber beliebig benannt werden.

In Klassenmethoden (die mit dem classmethodDecorator erstellt wurden) bezieht sich das erste Argument auf das Klassenobjekt selbst und heißt konventionell cls; diese werden hauptsächlich für vererbbare Konstruktoren verwendet, bei denen die Verwendung der Klasse als Parameter eine Unterklasse des Konstruktors ermöglicht. In statischen Methoden (die mit dem staticmethodDecorator erstellt wurden) existiert kein spezielles erstes Argument.

Rost

In Rust werden Typen getrennt von den ihnen zugeordneten Funktionen deklariert. Funktionen, die analog zu Instanzmethoden in traditionelleren objektorientierten Sprachen entworfen wurden, müssen explizit selfals ersten Parameter verwendet werden. Diese Funktionen können dann mit instance.method()Syntax Sugar aufgerufen werden . Zum Beispiel:

struct Foo {
    bar: i32,
}

impl Foo {
    fn new() -> Foo {
        Foo { bar: 0, }
    }
    fn refer(&self) {
        println!("{}", self.bar);
    }
    fn mutate(&mut self, baz: i32) {
        self.bar = baz;
    }
    fn consume(self) {
        self.refer();
    }
}

Dies definiert einen Typ, Fooder über vier zugehörige Funktionen verfügt. Die erste, Foo::new(), ist keine Instanzfunktion und muss mit dem Typpräfix angegeben werden. Die verbleibenden drei nehmen alle einen selfParameter auf verschiedene Weise entgegen und können in einer FooInstanz mit der Punktnotationssyntax Zucker aufgerufen werden , was dem Aufrufen des typqualifizierten Funktionsnamens mit einem expliziten selfersten Parameter entspricht.

let foo = Foo::new(); // must called as a type-specified function
foo.refer(); // prints "0". Foo::refer() has read-only access to the foo instance
foo.mutate(5); // mutates foo in place, permitted by the &mut specification
foo.consume(); // prints "5" and destroys foo, as Foo::consume() takes full ownership of self

//  equivalent to foo.refer()
Foo::refer(foo); // compilation error: foo is out of scope

Selbst

Die Self- Sprache ist nach dieser Verwendung von "self" benannt.

Xbase++

Selfwird ausschließlich innerhalb von Methoden einer Klasse verwendet. Eine andere Möglichkeit, darauf zu verweisen, Selfist die Verwendung von ::.

Siehe auch

Verweise

Weiterlesen