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 self
oder 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, this
um 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: this
ist 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 this
Schlüsselwort enthält . Nachdem ein Objekt richtig konstruiert oder instanziiert wurde, this
ist 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 this
im globalen Bereich außerhalb des Dokumentobjekts gespeichert ist; this
bezieht 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 this
or self
ein 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 this
oder 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 &self
oder 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 cls
für den Zugriff auf das Klassenobjekt .
Feinheiten und Schwierigkeiten
Wenn lexikalisches Scoping verwendet wird, um abzuleiten this
, kann die Verwendung von this
im Code, obwohl nicht illegal, bei einem Wartungsprogrammierer Warnglocken läuten lassen, obwohl es this
in diesem Fall immer noch legitime Verwendungen von gibt, wie z gleichen Namens, oder wenn die Methode eine Referenz auf das aktuelle Objekt, dh auf this
sich selbst, zurückgeben möchte .
In einigen Compilern (zum Beispiel GCC ) können Zeiger auf C++-Instanzmethoden mit einem expliziten this
Zeigerparameter direkt in einen Zeiger eines anderen Typs umgewandelt werden.
Offene Rekursion
Die Dispatch-Semantik von this
, nämlich dass Methodenaufrufe this
dynamisch 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++ ( this
aus Gründen der Übersichtlichkeit ein explizites , wenn auch nicht notwendig) die this
Bindung 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 factorial
Methode 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 this
standardmäß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
public
Methoden aufthis
. - Code, der intern (durch Aufruf von anderen Methoden derselben Klasse) wiederverwendet werden kann, wird in eine
protected
oderprivate
-Methode gekapselt ; wenn sie den Benutzern auch direkt zugänglich gemacht werden muss,public
ruft 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 this
Zeiger ändern; Auf diese Weise konnte ein Programmierer ändern, an welchem Objekt eine Methode arbeitete. Diese Funktion wurde schließlich entfernt und ist jetzt this
in C++ ein r-Wert .
Frühe Versionen von C++ enthielten keine Referenzen, und es wurde vorgeschlagen, dass es sich bei C++ von Anfang this
an 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 this
in C# funktioniert für Referenztypen genauso wie in Java. Jedoch innerhalb von C # Typen Wert , this
hat 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 this
C# 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 localAndFieldname
zu 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 this
als Zeiger auf die Instanz des Objekts verwendet, an das die Methode gebunden ist, während es in D2 den Charakter eines impliziten ref
Funktionsarguments 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, Current
um auf die aktuelle Klasse und ihre Features zu verweisen. Die Verwendung des Schlüsselworts Current
ist optional, da das Schlüsselwort Current
impliziert 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 Current
den Aufruf des einfachen `foo'.
Zeile 10 (unten) hat den expliziten Verweis auf Current
den 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 Current
vorgeschrieben 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 this
ist 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, this
kann niemals null sein.
JavaScript
In JavaScript, einer Programmier- oder Skriptsprache, die häufig in Webbrowsern verwendet wird, this
ist es ein wichtiges Schlüsselwort, obwohl es davon abhängt, wo es verwendet wird.
- Bei Verwendung außerhalb einer Funktion im globalen Raum
this
bezieht sich das Objekt auf das umschließende Objekt, das in diesem Fall das umschließende Browserfenster istwindow
. - Bei Verwendung in einer im globalen Raum definierten Funktion
this
hängt die Bedeutung des Schlüsselworts davon ab, wie die Funktion aufgerufen wird. Wenn eine solche Funktion direkt aufgerufen wird (zBf(x)
),this
verweist 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 esundefined
). Wenn eine globale Funktion enthaltendthis
als Teil des Eventhandlers eines Elements im Dokumentobjekt aufgerufenthis
wird , wird jedoch auf das aufrufende HTML-Element verwiesen. - Wenn eine Methode mit dem
new
Schlüsselwort (zBvar c = new Thing()
) aufgerufen wird, dannthis
bezieht 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)
),this
wird auf das Objekt verwiesen, in dem die Funktion enthalten ist. Es ist sogar möglich,this
beim Aufrufen einer Funktion manuell anzugeben , indem Sie die.call()
oder.apply()
-Methoden des Funktionsobjekts verwenden. Der Methodenaufrufobj.f(x)
könnte beispielsweise auch alsobj.f.call(obj, x)
.
Um die unterschiedliche Bedeutung von this
in verschachtelten Funktionen wie DOM-Ereignishandlern zu umgehen, ist es in JavaScript üblich, die this
Referenz des aufrufenden Objekts in einer Variablen (üblicherweise that
oder 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 this
und das zugehörige Schlüsselwort self
(im Gegensatz zu den meisten anderen Sprachen, die dazu neigen, das eine oder andere zu verwenden), wobei self
es speziell auf Webarbeiter beschränkt ist.
Schließlich enthält JavaScript das globalThis
Schlüsselwort , um zuverlässig auf das globale Objekt (window oder äquivalent) zu verweisen .
Lua
In Lua self
wird 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 self
Programmierern 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, $this
beschreibt 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 classmethod
Decorator 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 staticmethod
Decorator 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 self
als 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, Foo
der ü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 self
Parameter auf verschiedene Weise entgegen und können in einer Foo
Instanz mit der Punktnotationssyntax Zucker aufgerufen werden , was dem Aufrufen des typqualifizierten Funktionsnamens mit einem expliziten self
ersten 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++
Self
wird ausschließlich innerhalb von Methoden einer Klasse verwendet. Eine andere Möglichkeit, darauf zu verweisen, Self
ist die Verwendung von ::
.
Siehe auch
- Anonyme Rekursion – Rekursion ohne Aufruf einer Funktion mit Namen
- Vererbung (objektorientierte Programmierung) – Mechanismus zum Basieren eines Objekts oder einer Klasse auf einem anderen Objekt oder einer anderen Klasse, wobei eine ähnliche Implementierung beibehalten wird
- Selbstreferenz – Satz, Idee oder Formel, die sich auf sich selbst bezieht
- Schizophrenie (objektorientierte Programmierung) – Komplikationen durch Delegation und verwandte Techniken in der objektorientierten Programmierung
- Programmsegmentpräfix – Datenstruktur in DOS
Verweise
Weiterlesen
- Meyers, Scott, 1995. Effektiveres C++: 35 neue Möglichkeiten zur Verbesserung Ihrer Programme und Designs . ISBN 0-201-63371-X Scott Meyers
- Stroustrup, Bjarne, 1994. Das Design und die Evolution von C++ . Addison-Wesley-Pub. Co. ISBN 0-201-54330-3 Bjarne Stroustrup