this , self y Me son palabras clave utilizadas en algunos lenguajes de programación de computadoras para referirse al objeto, clase u otra entidad de la que forma parte el código que se ejecuta actualmente. La entidad a la que se hace referencia depende, por tanto, del contexto de ejecución (como a qué objeto se llama su método). Los distintos lenguajes de programación utilizan estas palabras clave de formas ligeramente diferentes. En idiomas donde una palabra clave como "esto" es obligatoria, la palabra clave es la única forma de acceder a los datos y métodos almacenados en el objeto actual. Cuando son opcionales, estas palabras clave pueden eliminar la ambigüedad de variables y funciones con el mismo nombre.
En muchos lenguajes de programación orientados a objetos , (también llamada o ) es una variable que se utiliza en métodos de instancia para referirse al objeto sobre el que se está trabajando. El primer lenguaje OO, SIMULA 67 , se utiliza para hacer referencia explícita al objeto local. [1] : 4.3.2.3 C++ y los lenguajes que derivan de él en estilo (como Java , C# , D y PHP ) también usan generalmente . Smalltalk y otros, como Object Pascal , Perl , Python , Ruby , Rust , Objective-C , DataFlex y Swift , utilizan . Visual Basic de Microsoft utiliza .this
self
Me
this
this
self
Me
El concepto es similar en todos los lenguajes: this
suele ser una referencia o puntero inmutable que hace referencia al objeto actual; el objeto actual suele ser el código que actúa como "padre" o "invocante" de la propiedad , método , subrutina o función que contiene la this
palabra clave. Una vez que un objeto se construye o crea una instancia correctamente, this
siempre hay una referencia válida. Algunos idiomas lo requieren explícitamente; otros usan el alcance léxico para usarlo implícitamente y hacer visibles los símbolos dentro de su clase. O, alternativamente, el objeto actual al que hace referencia this
puede ser un objeto de código independiente que ha llamado a la función o método que contiene la palabra clave this
. Esto sucede, por ejemplo, cuando un controlador de eventos de JavaScript adjunto a una etiqueta HTML en una página web llama a una función que contiene la palabra clave this
almacenada en el espacio global fuera del objeto del documento; en ese contexto, this
se referirá al elemento de la página dentro del objeto del documento, no al objeto de la ventana adjunto. [2]
En algunos lenguajes, por ejemplo C++, Java y Raku, this
or self
es una palabra clave y la variable existe automáticamente en los métodos de instancia. En otros, por ejemplo, Python, Rust y Perl 5, el primer parámetro de un método de instancia es dicha referencia. Es necesario especificarlo explícitamente. En Python y Perl, no es necesario que el parámetro tenga nombre this
o self
; El programador puede nombrarlo libremente como cualquier otro parámetro. Sin embargo, por convención informal, el primer parámetro de un método de instancia en Perl o Python se denomina self
. Rust requiere que se llame al objeto self &self
o self
, dependiendo de si la función invocada toma prestado el invocante o lo mueve, respectivamente.
Los métodos estáticos en C++ o Java no están asociados con instancias sino con clases, por lo que no pueden usarse this
porque no hay ningún objeto. En otros lenguajes, como Ruby, Smalltalk, Objective-C o Swift, el método está asociado con un objeto de clase que se pasa como this
y se denominan métodos de clase . Para los métodos de clase, Python utiliza cls
para acceder al objeto de clase .
Cuando se utiliza el alcance léxico para inferir this
, el uso de this
en el código, aunque no es ilegal, puede hacer sonar la alarma a un programador de mantenimiento, aunque todavía existen usos legítimos de this
en este caso, como hacer referencia a variables de instancia ocultas por variables locales del mismo nombre, o si el método quiere devolver una referencia al objeto actual, es decir this
, a sí mismo.
En algunos compiladores (por ejemplo, GCC ), los punteros a métodos de instancia de C++ se pueden convertir directamente a un puntero de otro tipo, con un this
parámetro de puntero explícito. [3]
La semántica de despacho de this
, es decir, que las llamadas a métodos this
se envían dinámicamente, se conoce como recursividad abierta y significa que estos métodos pueden ser anulados por clases u objetos derivados. Por el contrario, la recursividad directa con nombre o la recursividad anónima de una función utiliza recursividad cerrada , con vinculación anticipada. Por ejemplo, en el siguiente código Perl para el factorial, el token __SUB__
es una referencia a la función actual:
utilizar la función ":5.16" ; sub { mi $x = cambio ; $x == 0 ? 1 : $x * __SUB__ -> ( $x - 1 ); }
Por el contrario, en C++ (usando un explícito this
para mayor claridad, aunque no es necesario) se this
vincula al objeto en sí, pero si el método de clase se declaró "virtual", es decir, polimórfico en la base, se resuelve mediante envío dinámico ( enlace tardío ) de modo que las clases derivadas pueden anularlo.
int sin signo factorial ( int sin signo n ) { si ( n == 0 ) devuelve 1 ; de lo contrario, devuelve n * this -> factorial ( n - 1 ); }
Este ejemplo es artificial ya que se trata de recursividad directa, por lo que anular el factorial
método anularía esta función; ejemplos más naturales son cuando un método en una clase derivada llama al mismo método en una clase base, o en casos de recursividad mutua. [4] [5]
El frágil problema de la clase base se ha atribuido a la recursividad abierta, con la sugerencia de que invocar métodos por this
defecto a la recursividad cerrada (despacho estático, enlace temprano) en lugar de recursividad abierta (despacho dinámico, enlace tardío), solo usando la recursividad abierta cuando sea específicamente solicitado; Las llamadas externas (que no utilizan this
) se enviarán dinámicamente como de costumbre. [6] [7] La forma en que esto se resuelve en la práctica en el JDK es a través de una determinada disciplina de programación; esta disciplina ha sido formalizada por C. Ruby y GT Leavens; consta de las siguientes reglas: [8]
public
métodos en this
.protected
o ; private
Si también necesita exponerse directamente a los usuarios, entonces un public
método contenedor llama al método interno.Las primeras versiones de C++ permitirían this
cambiar el puntero; Al hacerlo, un programador podría cambiar en qué objeto estaba trabajando un método. Esta característica finalmente se eliminó y ahora this
en C++ es un valor r . [9]
Las primeras versiones de C++ no incluían referencias y se ha sugerido que si hubieran estado así en C++ desde el principio, this
habrían sido una referencia, no un puntero. [10]
C++ permite que los objetos se destruyan a sí mismos con la declaración del código fuente: delete this
.
La palabra clave this
en C# funciona de la misma manera que en Java, para tipos de referencia. Sin embargo, dentro de los tipos de valores de C# , this
tiene una semántica bastante diferente, es similar a una referencia de variable mutable ordinaria e incluso puede aparecer en el lado izquierdo de una asignación.
Un uso de this
en C# es permitir la referencia a una variable de campo externo dentro de un método que contiene una variable local que tiene el mismo nombre. En tal situación, por ejemplo, la declaración var n = localAndFieldname;
dentro del método asignará el tipo y el valor de la variable local localAndFieldname
a n
, mientras que la declaración var n = this.localAndFieldname;
asignará el tipo y el valor de la variable del campo externo a n
. [11]
En D this
, una clase, estructura o método de unión se refiere a una referencia inmutable de la instancia del agregado adjunto. Las clases son tipos de referencia y las estructuras y uniones son tipos de valores. En la primera versión de D, la palabra clave this
se utiliza como puntero a la instancia del objeto al que está vinculado el método, mientras que en D2 tiene el carácter de un refargumento de función implícito.
En el lenguaje de programación Dylan , que es un lenguaje orientado a objetos que admite múltiples métodos y no tiene un concepto de this
, enviar un mensaje a un objeto aún se mantiene en la sintaxis. Los dos formularios siguientes funcionan de la misma manera; las diferencias son solo azúcar sintáctica .
objeto.método(param1, param2)
y
método (objeto, parámetro1, parámetro2)
Dentro de un texto de clase, el tipo actual es el tipo obtenido de la clase actual . Dentro de las características (rutinas, comandos y consultas) de una clase, se puede usar la palabra clave Current
para hacer referencia a la clase actual y sus características. El uso de la palabra clave Current
es opcional ya que la palabra clave Current
está implícita simplemente haciendo referencia abiertamente al nombre de la característica de clase actual. Por ejemplo: uno podría tener una característica `foo' en una clase MY_CLASS y hacer referencia a ella mediante:
clase MI CLASE característica - Acceso foo : ENTERO mi_función : ENTERO hacer Resultado := foo fin fin
[12]
La línea #10 (arriba) tiene la referencia implícita Current
mediante la llamada al simple `foo'.
La línea #10 (a continuación) tiene la referencia explícita Current
mediante la llamada a `Current.foo'.
clase MI CLASE característica - Acceso foo : ENTERO mi_función : ENTERO hacer Resultado := Actual . foo fin fin
Cualquiera de los dos enfoques es aceptable para el compilador, pero se prefiere la versión implícita (p. ej. x := foo
) porque es menos detallada.
Al igual que con otros idiomas, hay ocasiones en las que el uso de la palabra clave Current
es obligatorio, como por ejemplo:
clase MI CLASE característica - Acceso mi_comando -- Crea MY_OTHER_CLASS con "Actual" local x : MI_OTHER_CLASS hacer crear x . make_with_something ( Actual ) fin fin
En el caso del código anterior, la llamada en la línea 11 a make_with_something pasa la clase actual pasando explícitamente la palabra clave Current
.
La palabra clave this
es una palabra clave del lenguaje Java que representa la instancia actual de la clase en la que aparece. Se utiliza para acceder a variables y métodos de clase.
Dado que todos los métodos de instancia son virtuales en Java, this
nunca pueden ser nulos. [13]
En JavaScript, que es un lenguaje de programación o scripting utilizado ampliamente en navegadores web, this
es una palabra clave importante, aunque su evaluación depende de dónde se utiliza.
this
se refiere al objeto circundante, que en este caso es la ventana del navegador circundante, el window
objeto.this
a qué se refiere la palabra clave depende de cómo se llama la función. Cuando dicha función se llama directamente (por ejemplo f(x)
), this
se hará referencia al espacio global en el que se define la función y en el que también pueden existir otras funciones y variables globales (o en modo estricto, es undefined
). Sin embargo , si una función global que contiene this
se llama como parte del controlador de eventos de un elemento en el objeto del documento, this
se referirá al elemento HTML que llama.new
palabra clave (por ejemplo var c = new Thing()
), dentro de la cosa this
se hace referencia al objeto de la cosa en sí.obj.f(x)
), this
se referirá al objeto que contiene la función. [14] [15] Incluso es posible especificar manualmente this
al llamar a una función, utilizando los métodos .call()
o .apply()
del objeto de función. [16] Por ejemplo, la llamada al método obj.f(x)
también podría escribirse como obj.f.call(obj, x)
.Para solucionar el significado diferente de this
funciones anidadas como los controladores de eventos DOM, es un modismo común en JavaScript guardar la this
referencia del objeto que llama en una variable (comúnmente llamada that
o self
) y luego usar la variable para hacer referencia al objeto que llama. objeto en funciones anidadas.
Por ejemplo:
// En este ejemplo $ es una referencia a la biblioteca jQuery $ ( ".element" ). hover ( function () { // Aquí, tanto esto como aquello apuntan al elemento debajo del cursor del mouse. var that = this ; $ ( this ). find ( '.elements' ). each ( function () { // Aquí , esto apunta al elemento DOM que se está iterando. // Sin embargo , todavía apunta al elemento debajo del cursor del mouse .
En particular, JavaScript utiliza ambos this
y la palabra clave relacionada self
[17] (a diferencia de la mayoría de los otros lenguajes que tienden a emplear uno u otro), y self
está restringido específicamente a los trabajadores web. [18]
Finalmente, como forma confiable de hacer referencia específica al objeto global (ventana o equivalente), JavaScript incluye la globalThis
palabra clave. [19]
En Lua, self
se crea como azúcar sintáctico cuando las funciones se definen mediante el :
operador. [20] Al invocar un método usando :
, el objeto que se indexa se proporcionará implícitamente como el primer argumento de la función que se invoca.
Por ejemplo, las dos funciones siguientes son equivalentes:
objeto local = {}función objeto . foo ( arg1 , arg2 ) print ( arg1 , arg2 ) - no se puede usar "self" aquífunción obj : bar ( arg ) print ( self , arg ) - "self" es un primer argumento implícito antes del final del argumento-- Todas las funciones se pueden invocar en ambos sentidos, con "." o con ":"obj : foo ( "Foo" ) - equivalente a obj.foo(obj, "Foo") obj . bar ( obj , "Bar" ) - equivalente a obj:bar("Bar")
Lua en sí no está orientado a objetos, pero cuando se combina con otra característica llamada metatablas, el uso de self
permite a los programadores definir funciones de una manera similar a la programación orientada a objetos.
En PowerShell, la variable automática $_
especial contiene el objeto actual en el objeto de canalización. Puede utilizar esta variable en comandos que realizan una acción en cada objeto o en objetos seleccionados en una canalización. [21]
"uno" , "dos" , "tres" | % { escribir $_ }
También a partir de PowerShell 5.0, que agrega una sintaxis formal para definir clases y otros tipos definidos por el usuario, la variable [22] $this
describe la instancia actual del objeto.
En Python, no hay ninguna palabra clave para this
. Cuando se llama a una función miembro en un objeto, invoca la función miembro con el mismo nombre en el objeto de clase del objeto, y el objeto se vincula automáticamente al primer argumento de la función. Por tanto, el primer parámetro obligatorio de los métodos de instancia sirve como this
; este parámetro se denomina convencionalmente self
, pero se le puede dar cualquier nombre.
En los métodos de clase (creados con el classmethod
decorador), el primer argumento se refiere al objeto de clase en sí y se llama convencionalmente cls
; estos se utilizan principalmente para constructores heredables, [23] donde el uso de la clase como parámetro permite subclasificar el constructor. En los métodos estáticos (creados con el staticmethod
decorador), no existe ningún primer argumento especial.
En Rust, los tipos se declaran por separado de las funciones asociadas a ellos. Las funciones diseñadas para ser análogas a los métodos de instancia en lenguajes más tradicionalmente orientados a objetos deben tomar explícitamente self
como primer parámetro. Luego, estas funciones se pueden llamar usando instance.method()
azúcar de sintaxis. Por ejemplo:
estructura Foo { barra : i32 , } impl Foo { fn nuevo () -> Foo { Foo { barra : 0 , } } fn referir ( & self ) { println! ( "{}" , self .bar ) ; } fn mutar ( & mut self , baz : i32 ) { self . barra = baz ; } fn consumir ( self ) { self . referirse (); } }
Esto define un tipo, Foo
que tiene cuatro funciones asociadas. La primera, Foo::new()
no es una función de instancia y debe especificarse con el prefijo de tipo. Los tres restantes toman un self
parámetro de diversas formas y se pueden invocar en una Foo
instancia utilizando la sintaxis de notación de puntos, lo que equivale a llamar al nombre de la función calificada por tipo con un self
primer parámetro explícito.
let mut foo = Foo :: nuevo (); // debe llamarse como una función foo de tipo especificado . referirse (); // imprime "0". Foo::refer() tiene acceso de solo lectura a la instancia de foo foo . mutar ( 5 ); // muta foo en su lugar, permitido por la especificación &mut, necesita que foo se declare mut foo . consumir (); // imprime "5" y destruye foo, ya que Foo::consume() toma plena propiedad de sí mismo // equivalente a foo.refer() Foo :: referir ( foo ); // error de compilación: foo está fuera de alcance
El lenguaje Self lleva el nombre de este uso de "self".
Self
se usa estrictamente dentro de los métodos de una clase. Otra forma de referirse Self
es utilizar ::
.