this (programmation informatique) - this (computer programming)

this , self et Me sont des mots - clés utilisés dans certains langages de programmation informatique pour désigner l'objet, la classe ou une autre entité dont fait partie le code en cours d'exécution. L'entité référencée par ces mots-clés dépend donc du contexte d'exécution (tel que l'objet dont la méthode est appelée). Différents langages de programmation utilisent ces mots-clés de manière légèrement différente. Dans les langages où un mot-clé comme "ceci" est obligatoire, le mot-clé est le seul moyen d'accéder aux données et aux méthodes stockées dans l'objet courant. Lorsqu'elles sont facultatives, elles peuvent lever l'ambiguïté des variables et des fonctions portant le même nom.

Programmation orientée objet

Dans de nombreux langages de programmation orientés objet , this(également appelé selfou Me) est une variable utilisée dans les méthodes d'instance pour faire référence à l'objet sur lequel elles travaillent. Le premier langage OO, SIMULA 67 , utilisé thispour référencer explicitement l'objet local. C++ et les langages qui en dérivent dans le style (tels que Java , C# , D et PHP ) utilisent également généralement this. Smalltalk et d'autres, tels que Object Pascal , Perl , Python , Ruby , Rust , Objective-C , DataFlex et Swift , utilisent self. Visual Basic de Microsoft utilise Me.

Le concept est similaire dans tous les langages : thisest généralement une référence ou un pointeur immuable qui fait référence à l'objet courant ; l'objet actuel étant souvent le code qui agit comme « parent » de la propriété , de la méthode , de la sous-routine ou de la fonction qui contient le thismot - clé. Une fois qu'un objet est correctement construit ou instancié, il thisy a toujours une référence valide. Certaines langues l'exigent explicitement ; d'autres utilisent la portée lexicale pour l'utiliser implicitement pour rendre visibles les symboles au sein de leur classe. Ou bien, l'objet courant référencé par thispeut être un objet de code indépendant qui a appelé la fonction ou la méthode contenant le mot-clé this. Une telle chose se produit, par exemple, lorsqu'un gestionnaire d'événements JavaScript attaché à une balise HTML dans une page Web appelle une fonction contenant le mot-clé thisstocké dans l'espace global à l'extérieur de l'objet document ; dans ce contexte, thisfera référence à l'élément de page dans l'objet document, et non à l'objet fenêtre englobant.

Dans certains langages, par exemple C++ et Java, thisou selfest un mot - clé , et la variable existe automatiquement dans les méthodes d'instance. Dans d'autres, par exemple Python, Rust et Perl 5, le premier paramètre d'une méthode d'instance est une telle référence. Il doit être spécifié explicitement. En Python et Perl, le paramètre ne doit pas nécessairement être nommé thisou self; il peut être nommé librement par le programmeur comme tout autre paramètre. Cependant, par convention informelle, le premier paramètre d'une méthode d'instance en Perl ou Python est nommé self. Rust exige que l'objet self soit appelé &selfou self, selon que la fonction invoquée emprunte l'invocateur ou le déplace, respectivement.

Les méthodes statiques en C++ ou Java ne sont pas associées à des instances mais à des classes, et ne peuvent donc pas utiliser this, car il n'y a pas d'objet. Dans d'autres langages, tels que Ruby, Smalltalk, Objective-C ou Swift, la méthode est associée à un objet de classe qui est passé en tant que this, et elles sont appelées méthodes de classe . Pour les méthodes de classe, Python utilise clspour accéder à l' objet de classe .

Subtilités et difficultés

Lorsque la portée lexicale est utilisée pour déduire this, l'utilisation de thisin code, bien qu'elle ne soit pas illégale, peut alerter un programmeur de maintenance, bien qu'il existe encore des utilisations légitimes de thisdans ce cas, telles que la référence à des variables d'instance cachées par des variables locales du même nom, ou si la méthode veut renvoyer une référence à l'objet courant, c'est this-à- dire lui-même.

Dans certains compilateurs (par exemple GCC ), les pointeurs vers les méthodes d'instance C++ peuvent être directement convertis en un pointeur d'un autre type, avec un thisparamètre de pointeur explicite .

Récursivité ouverte

La sémantique de répartition de this, à savoir que les appels de méthode thissont répartis dynamiquement, est connue sous le nom de récursivité ouverte , et signifie que ces méthodes peuvent être remplacées par des classes ou des objets dérivés. En revanche, la récursivité nommée directe ou la récursivité anonyme d'une fonction utilise une récursivité fermée , avec une liaison anticipée. Par exemple, dans le code Perl suivant pour la factorielle, le jeton __SUB__est une référence à la fonction actuelle :

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

En revanche, en C++ (en utilisant un explicite thispour plus de clarté, bien que ce ne soit pas nécessaire) le thislien avec l'objet lui-même, mais si la méthode de classe a été déclarée "virtuelle", c'est-à-dire polymorphe dans la base, elle est résolue via un dispatch dynamique ( late binding ) de sorte que les classes dérivées peuvent le remplacer.

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

Cet exemple est artificiel, puisqu'il s'agit d'une récursivité directe, donc factorialécraser la méthode écraserait cette fonction ; des exemples plus naturels sont lorsqu'une méthode dans une classe dérivée appelle la même méthode dans une classe de base, ou en cas de récursivité mutuelle.

Le problème de la classe de base fragile a été imputé à la récursivité ouverte, avec la suggestion d'invoquer des méthodes sur la thisrécursivité fermée par défaut (répartition statique, liaison précoce) plutôt que sur la récursivité ouverte (répartition dynamique, liaison tardive), en utilisant uniquement la récursivité ouverte lorsqu'elle est spécifiquement demandé; les appels externes (n'utilisant pas this) seraient distribués dynamiquement comme d'habitude. La façon dont cela est résolu en pratique dans le JDK passe par une certaine discipline de programmeur ; cette discipline a été formalisée par C. Ruby et GT Leavens ; il se compose essentiellement des règles suivantes :

  • Aucun code n'appelle de publicméthodes sur this.
  • Le code qui peut être réutilisé en interne (par invocation depuis d'autres méthodes de la même classe) est encapsulé dans une méthode protectedou private; si elle doit également être exposée directement aux utilisateurs, une publicméthode wrapper appelle la méthode interne.
  • La recommandation précédente peut être assouplie pour les méthodes pures .

Implémentations

C++

Les premières versions de C++ permettaient de thismodifier le pointeur ; ce faisant, un programmeur pouvait changer l'objet sur lequel une méthode travaillait. Cette fonctionnalité a finalement été supprimée, et maintenant thisen C++ est une valeur r .

Les premières versions de C++ n'incluaient pas de références et il a été suggéré que si elles l'avaient été en C++ depuis le début, thiscela aurait été une référence, pas un pointeur.

C++ permet aux objets de s'autodétruire avec l'instruction de code source : delete this.

C#

Le mot-clé thisen C# fonctionne de la même manière qu'en Java, pour les types référence. Cependant, dans les types de valeur C# , thisa une sémantique assez différente, étant similaire à une référence de variable mutable ordinaire, et peut même se produire sur le côté gauche d'une affectation.

Une utilisation de thisen C# est d'autoriser la référence à une variable de champ externe dans une méthode qui contient une variable locale portant le même nom. Dans une telle situation, par exemple, l'instruction var n = localAndFieldname;dans la méthode affectera le type et la valeur de la variable locale localAndFieldnameà n, tandis que l'instruction var n = this.localAndFieldname;affectera le type et la valeur de la variable de champ externe à n.

En D this dans une classe, la méthode struct ou union fait référence à une référence immuable de l'instance de l'agrégat englobant. Les classes sont des types référence , les structs et les unions sont des types valeur. Dans la première version de D, le mot this- clé est utilisé comme pointeur vers l'instance de l'objet auquel la méthode est liée, tandis que dans D2, il a le caractère d'un refargument de fonction implicite .

Dylan

Dans le langage de programmation Dylan , qui est un langage orienté objet qui prend en charge les multiméthodes et n'a pas de concept de this, l'envoi d'un message à un objet est toujours conservé dans la syntaxe. Les deux formulaires ci-dessous fonctionnent de la même manière ; les différences ne sont que du sucre syntaxique .

object.method(param1, param2)

et

method (object, param1, param2)

Eiffel

Dans un texte de classe, le type courant est le type obtenu à partir de la classe courante . Dans les fonctionnalités (routines, commandes et requêtes) d'une classe, on peut utiliser le mot-clé Currentpour référencer la classe actuelle et ses fonctionnalités. L'utilisation du mot Current- clé est facultative car le mot Current- clé est implicite en se référant simplement ouvertement au nom de l'entité de classe actuelle. Par exemple : On pourrait avoir une caractéristique 'foo' dans une classe MY_CLASS et s'y référer par :

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

La ligne #10 (ci-dessus) a la référence implicite à Currentpar l'appel au simple `foo'.

La ligne #10 (ci-dessous) a la référence explicite à Currentpar l'appel à `Current.foo'.

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

L'une ou l'autre approche est acceptable pour le compilateur, mais la version implicite (par exemple x := foo) est préférée car elle est moins détaillée.

Comme avec d'autres langues, il y a des moments où l'utilisation du mot Current- clé est obligatoire, comme :

  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

Dans le cas du code ci-dessus, l'appel de la ligne #11 à make_with_something passe la classe actuelle en passant explicitement le mot-clé Current.

Java

Le mot this- clé est un mot-clé du langage Java qui représente l'instance actuelle de la classe dans laquelle il apparaît. Il est utilisé pour accéder aux variables de classe et aux méthodes.

Étant donné que toutes les méthodes d'instance sont virtuelles en Java, thiselles ne peuvent jamais être nulles.

JavaScript

En JavaScript, qui est un langage de programmation ou de script largement utilisé dans les navigateurs Web, thisest un mot-clé important, bien que ce qu'il évalue dépend de l'endroit où il est utilisé.

  • Lorsqu'il est utilisé en dehors de toute fonction, dans l'espace global, thisfait référence à l'objet englobant, qui dans ce cas est la fenêtre du navigateur englobant, l' windowobjet.
  • Lorsqu'il est utilisé dans une fonction définie dans l'espace global, ce à quoi le mot-clé thisfait référence dépend de la façon dont la fonction est appelée. Lorsqu'une telle fonction est appelée directement (par exemple f(x)), thisrenvoie à l'espace global dans lequel la fonction est définie, et dans lequel d'autres fonctions et variables globales peuvent également exister (ou en mode strict, c'est undefined). Si une fonction globale contenant thisest appelée dans le cadre du gestionnaire d'événements d'un élément dans l'objet document, cependant, thisfera référence à l'élément HTML appelant.
  • Lorsqu'une méthode est appelée à l'aide du newmot - clé (par exemple var c = new Thing()), alors dans Thing thisfait référence à l'objet Thing lui-même.
  • Lorsqu'une fonction est attachée en tant que propriété d'un objet et appelée en tant que méthode de cet objet (par exemple obj.f(x)), thisfera référence à l'objet dans lequel la fonction est contenue. Il est même possible de spécifier manuellement thislors de l'appel d'une fonction, en utilisant les méthodes .call()ou .apply()de l'objet fonction. Par exemple, l'appel de méthode obj.f(x)peut également être écrit sous la forme obj.f.call(obj, x).

Pour contourner les différentes significations des thisfonctions imbriquées telles que les gestionnaires d'événements DOM, il est courant en JavaScript d'enregistrer la thisréférence de l'objet appelant dans une variable (communément appelée thatou self), puis d'utiliser la variable pour faire référence à l'appel objet dans les fonctions imbriquées.

Par exemple:

// 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");
    });
});

Notamment, JavaScript utilise les deux thiset le mot-clé associé self(contrairement à la plupart des autres langages qui ont tendance à utiliser l'un ou l'autre), en selfse limitant spécifiquement aux travailleurs Web.

Enfin, comme moyen fiable de référencer spécifiquement l'objet global (fenêtre ou équivalent), JavaScript propose le globalThismot - clé.

Lua

En Lua, selfest créé en tant que sucre syntaxique lorsque les fonctions sont définies à l'aide de l' :opérateur. Lors de l'appel d'une méthode à l'aide de :, l'objet indexé sera implicitement donné comme premier argument à la fonction invoquée.

Par exemple, les deux fonctions suivantes sont équivalentes :

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 lui-même n'est pas orienté objet, mais lorsqu'il est combiné avec une autre fonctionnalité appelée métatables, l'utilisation de selfpermet aux programmeurs de définir des fonctions d'une manière qui ressemble à la programmation orientée objet.

PowerShell

Dans PowerShell, la variable automatique spéciale $_contient l'objet actuel dans l'objet de pipeline. Vous pouvez utiliser cette variable dans des commandes qui effectuent une action sur chaque objet ou sur des objets sélectionnés dans un pipeline.

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

En commençant également par PowerShell 5.0, qui ajoute une syntaxe formelle pour définir des classes et d'autres types définis par l'utilisateur, la $thisvariable décrit l'instance actuelle de l'objet.

Python

En Python, il n'y a pas de mot-clé pour this. Lorsqu'une fonction membre est appelée sur un objet, elle invoque la fonction membre du même nom sur l'objet de classe de l'objet, l'objet étant automatiquement lié au premier argument de la fonction. Ainsi, le premier paramètre obligatoire des méthodes d'instance sert de this; ce paramètre est conventionnellement nommé self, mais peut être nommé n'importe quoi.

Dans les méthodes de classe (créées avec le classmethoddécorateur), le premier argument fait référence à l'objet de classe lui-même, et est conventionnellement appelé cls; ceux-ci sont principalement utilisés pour les constructeurs héritables, où l'utilisation de la classe en tant que paramètre permet de sous-classer le constructeur. Dans les méthodes statiques (créées avec le staticmethoddécorateur), aucun premier argument spécial n'existe.

Rouiller

Dans Rust, les types sont déclarés séparément des fonctions qui leur sont associées. Les fonctions conçues pour être analogues aux méthodes d'instance dans les langages plus traditionnellement orientés objet doivent explicitement prendre selfcomme premier paramètre. Ces fonctions peuvent ensuite être appelées à l'aide de la instance.method()syntaxe sugar. Par exemple:

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();
    }
}

Ceci définit un type, Foo, qui a quatre fonctions associées. Le premier, Foo::new(), n'est pas une fonction d'instance et doit être spécifié avec le préfixe de type. Les trois autres prennent tous un selfparamètre de différentes manières et peuvent être appelés sur une Fooinstance à l'aide de la syntaxe de notation par points sugar, ce qui équivaut à appeler le nom de la fonction qualifiée avec un selfpremier paramètre explicite .

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

Soi

Le langage Self est nommé d'après cette utilisation de "self".

Xbase++

Selfest strictement utilisé dans les méthodes d'une classe. Une autre façon de se référer Selfest d'utiliser ::.

Voir également

Les références

Lectures complémentaires