this , self y Me son palabras clave que se utilizan 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 está ejecutando actualmente. La entidad a la que se refieren estas palabras clave depende, por tanto, del contexto de ejecución (por ejemplo, a qué objeto se llama su método). Los diferentes 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. Donde sea opcional, pueden eliminar la ambigüedad de variables y funciones con el mismo nombre.
Programación orientada a objetos
En muchos lenguajes de programación orientados a objetos , this
(también llamado self
o Me
) es una variable que se usa en métodos de instancia para referirse al objeto en el que están trabajando. El primer lenguaje OO, SIMULA 67 , se utiliza this
para hacer referencia explícita al objeto local. [1] : 4.3.2.3 C ++ y los lenguajes que derivan en estilo de él (como Java , C # , D y PHP ) también suelen utilizar this
. Smalltalk y otros, como Object Pascal , Perl , Python , Ruby , Rust , Objective-C , DataFlex y Swift , utilizan self
. Usos de Visual Basic de Microsoft Me
.
El concepto es similar en todos los lenguajes: this
suele ser una referencia o puntero inmutable que se refiere al objeto actual; el objeto actual suele ser el código que actúa como "padre" de la propiedad , método , subrutina o función que contiene la this
palabra clave. Una vez que un objeto está correctamente construido o instanciado, this
siempre es una referencia válida. Algunos idiomas lo requieren explícitamente; otros usan el alcance léxico para usarlo implícitamente para hacer visibles los símbolos dentro de su clase. O alternativamente, el objeto actual al que se hace referencia por 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 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 página dentro del objeto de documento, no al objeto de ventana adjunto. [2]
En algunos lenguajes, por ejemplo, C ++ y Java, this
o 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. Debe especificarse explícitamente. En Python y Perl, el parámetro no necesita necesariamente ser nombrado this
o self
; El programador puede nombrarlo libremente como cualquier otro parámetro. Sin embargo, por convención informal, se nombra el primer parámetro de un método de instancia en Perl o Python 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 se pueden usar 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 usa cls
para acceder al objeto de clase .
Sutilezas y dificultades
Cuando se utiliza el alcance léxico para inferir this
, el uso de this
en el código, aunque no es ilegal, puede generar señales de advertencia a un programador de mantenimiento, aunque todavía hay usos legítimos de this
en este caso, como referirse a variables de instancia ocultas por variables locales de 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 los 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]
Recursividad abierta
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 recursión anónima de una función utiliza la recursividad cerrada , con enlace temprano. Por ejemplo, en el siguiente código de Perl para el factorial, el token __SUB__
es una referencia a la función actual:
utilizar la función ": 5,16" ; sub { mi $ x = turno ; $ x == 0 ? 1 : $ x * __SUB__ -> ( $ x - 1 ); }
Por el contrario, en C ++ (usando un explícito this
para mayor claridad, aunque no es necesario), el this
enlace con el 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 ) para que las clases derivadas pueden anularlo.
unsigned int factorial ( unsigned int n ) { if ( n == 0 ) return 1 ; de lo contrario, devuelve n * esto -> factorial ( n - 1 ); }
Este ejemplo es artificial, ya que se trata de una recursividad directa, por lo que anular el factorial
método anularía esta función; Los 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 la invocación de métodos por this
defecto a la recursividad cerrada (envío estático, enlace temprano) en lugar de la recursividad abierta (envío dinámico, enlace tardío), solo usa la recursividad abierta cuando es específicamente solicitado; las llamadas externas (sin usar this
) se enviarían 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 programador; esta disciplina ha sido formalizada por C. Ruby y GT Leavens; básicamente consta de las siguientes reglas: [8]
- Ningún código invoca
public
métodos enthis
. - El código que se puede reutilizar internamente (mediante la invocación de otros métodos de la misma clase) se encapsula en un método
protected
oprivate
; si también necesita exponerse directamente a los usuarios, entonces unpublic
método contenedor llama al método interno. - La recomendación anterior se puede relajar para métodos puros .
Implementaciones
C ++
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 lo hubieran sido en C ++ desde el principio, this
habría sido una referencia, no un puntero. [10]
C ++ permite que los objetos se destruyen con la instrucción de código fuente: delete this
.
C#
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 ocurrir 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 valor de la variable local localAndFieldname
a n
, mientras que la declaración var n = this.localAndFieldname;
asignará el tipo y valor de la variable de campo exterior a n
. [11]
D
En D this
en una clase, el método de estructura o unión se refiere a una referencia inmutable de la instancia del agregado adjunto. Las clases son tipos de referencia , las estructuras y las uniones son tipos de valor. 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ícita .
Dylan
En el lenguaje de programación Dylan , que es un lenguaje orientado a objetos que admite métodos múltiples y no tiene un concepto de this
, enviar un mensaje a un objeto todavía se mantiene en la sintaxis. Las dos formas siguientes funcionan de la misma manera; las diferencias son solo azúcar sintáctica .
object.method (param1, param2)
y
método (objeto, param1, param2)
Eiffel
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 al nombre de la característica de la clase actual abiertamente. Por ejemplo: uno podría tener una característica 'foo' en una clase MY_CLASS y referirse a ella por:
clase MI CLASE característica - Acceso foo : INTEGER my_function : INTEGER hacer Resultado : = foo final final
[12]
La línea # 10 (arriba) tiene la referencia implícita a Current
la llamada a simple 'foo'.
La línea # 10 (abajo) tiene la referencia explícita a Current
la llamada a 'Current.foo'.
clase MI CLASE característica - Acceso foo : INTEGER my_function : INTEGER hacer Resultado : = Actual . foo final final
Cualquiera de los enfoques es aceptable para el compilador, pero x := foo
se prefiere la versión implícita (por ejemplo ), ya que 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 my_command - Crear MY_OTHER_CLASS con "Current" local x : MY_OTHER_CLASS hacer crear x . make_with_something ( actual ) final final
En el caso del código anterior, la llamada en la línea # 11 a make_with_something está pasando la clase actual pasando explícitamente la palabra clave Current
.
Java
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 métodos y variables de clase.
Dado que todos los métodos de instancia son virtuales en Java, this
nunca pueden ser nulos. [13]
JavaScript
En JavaScript, que es un lenguaje de programación o scripting que se usa ampliamente en los navegadores web, this
es una palabra clave importante, aunque lo que evalúa depende de dónde se use.
- Cuando se usa fuera de cualquier función, en el espacio global, se
this
refiere al objeto que lo encierra, que en este caso es la ventana del navegador que lo encierra, elwindow
objeto. - Cuando se usa en una función definida en el espacio global, a qué se
this
refiere la palabra clave depende de cómo se llame a la función. Cuando una función de este tipo se llama directamente (por ejemplof(x)
),this
se referirá 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 estrictoundefined
).this
Sin embargo,this
si se llama a una función global que contiene como parte del controlador de eventos de un elemento en el objeto de documento, se hará referencia al elemento HTML que realiza la llamada. - Cuando se llama a un método usando la
new
palabra clave (por ejemplovar c = new Thing()
), dentro de Thing sethis
refiere al objeto Thing en sí. - Cuando una función se adjunta como una propiedad de un objeto y se llama como un método de ese objeto (por ejemplo
obj.f(x)
),this
se referirá al objeto en el que está contenida la función. [14] [15] Incluso es posible especificar manualmentethis
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étodoobj.f(x)
también podría escribirse comoobj.f.call(obj, x)
.
Para evitar el significado diferente de this
en funciones anidadas, como los controladores de eventos DOM, es un lenguaje común en JavaScript guardar la this
referencia del objeto de llamada en una variable (comúnmente llamada that
o self
), y luego usar la variable para hacer referencia a la llamada. 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 ; $ ( esto ). buscar ( '.elementos' ). each ( function () { // Aquí, esto apunta al elemento DOM que se está iterando. // Sin embargo, eso todavía apunta al elemento debajo del cursor del mouse. $ ( this ). addClass ( "resaltar" ); }); });
Lua
En Lua, self
se crea como azúcar sintáctico cuando las funciones se definen utilizando el :
operador. [17] Cuando se invoca un método utilizando :
, el objeto que se indexa se dará implícitamente como el primer argumento de la función que se invoca.
Por ejemplo, las siguientes dos funciones son equivalentes:
obj local = {}función obj . foo ( arg1 , arg2 ) print ( arg1 , arg2 ) - no se puede usar "self" aquí al finalfunction obj : bar ( arg ) print ( self , arg ) - "self" es un primer argumento implícito antes del final de arg- 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 que se asemeja a la programación orientada a objetos.
Potencia Shell
En PowerShell, la variable automática especial $_
contiene el objeto actual en el objeto de canalización. Puede usar esta variable en comandos que realizan una acción en cada objeto o en objetos seleccionados en una canalización. [18]
"uno" , "dos" , "tres" | % { escribe $ _ }
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 [19] $this
describe la instancia actual del objeto.
Pitón
En Python, no hay una 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, con el objeto vinculado 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 tiene un nombre convencional self
, pero se puede nombrar de cualquier forma.
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, [20] 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 un primer argumento especial.
Oxido
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 orientados a objetos más tradicionales deben tomar explícitamente self
como su primer parámetro. A continuación, estas funciones se pueden llamar usando instance.method()
syntax sugar. Por ejemplo:
struct Foo { barra : i32 ,}impl Foo { fn nuevo () -> Foo { Foo { bar : 0 , } } fn referirse ( & self ) { println! ( "{}" , Sí . Bar ); } fn mutate ( & mut self , baz : i32 ) { yo . bar = baz ; } fn consume ( auto ) { yo . referir (); }}
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 en una variedad de formas y se pueden llamar en una Foo
instancia usando la sintaxis de notación de puntos sugar, que es equivalente a llamar al nombre de la función calificada por tipo con un self
primer parámetro explícito .
dejar foo = Foo :: new (); // debe llamarse como una función de tipo especificado foo . referir (); // imprime "0". Foo :: refer () tiene acceso de solo lectura a la instancia foo foo . mutar ( 5 ); // muta foo en su lugar, permitido por la especificación de & mut foo . consumir (); // imprime "5" y destruye foo, ya que Foo :: consume () toma posesión total de sí mismo // equivalente a foo.refer () Foo :: refer ( foo ); // error de compilación: foo está fuera de alcance
Uno mismo
El lenguaje del yo lleva el nombre de este uso de "yo".
Xbase ++
Self
se usa estrictamente dentro de los métodos de una clase. Otra forma de hacer referencia Self
es utilizar ::
.
Ver también
- Recursividad anónima : recursividad sin llamar a una función por su nombre
- Herencia (programación orientada a objetos) : el mecanismo de basar un objeto o clase en otro objeto o clase que conserva una implementación similar
- Autorreferencia : una oración, idea o fórmula que se refiere a sí misma.
- Esquizofrenia (programación orientada a objetos) : una complicación que surge de la delegación y técnicas relacionadas en la programación orientada a objetos
- Prefijo de segmento de programa : estructura de datos en DOS
Referencias
- ^ Dahl, Ole-Johan ; Myhrhaug, Bjørn; Nygaard, Kristen (1970). "Common Base Language, Norwegian Computing Center" .
- ^ Powell, Thomas A y Schneider, Fritz, 2012. JavaScript: La referencia completa, tercera edición. McGraw-Hill. Capítulo 11, Manejo de eventos , p 428. ISBN 978-0-07-174120-0
- ^ Uso de la colección de compiladores GNU (GCC) - Funciones miembro enlazadas
- ^ " Recursión cerrada y abierta ", Ralf Hinze , julio de 2007
- ^ Recursividad abierta , Lambda the Ultimate
- ^ " Recursión abierta selectiva: una solución al problema de la clase base frágil ", Jonathan Aldrich
- ^ " Recursión abierta selectiva: una solución al problema de la clase base frágil ", Lambda the Ultimate
- ^ Aldrich, Jonathan y Kevin Donnelly. " Recursividad abierta selectiva: razonamiento modular sobre componentes y herencia " . SAVCBS 2004 Especificación y verificación de sistemas basados en componentes (2004): 26. citando la solución adoptada por JDK C. Ruby y GT Leavens. "Creación segura de subclases correctas sin ver el código de superclase". En Sistemas, lenguajes y aplicaciones de programación orientada a objetos, octubre de 2000. doi : 10.1145 / 353171.353186 también disponible como informe técnico TR # 00-05d
- ^ ISO / IEC 14882: 2003 (E): Lenguajes de programación - C ++ . ISO / IEC. 2003.
- ^ Stroustrup: Preguntas frecuentes sobre estilo y técnica de C ++
- ^ De Smet, Bart, 2011. C # 4.0 desatado. Sams Publishing, Indianápolis, Estados Unidos. Capítulo 4, Language Essentials , p. 210. ISBN 978-0-672-33079-7
- ^ NOTA: Los números de línea son solo para fines de referencia. Eiffel no tiene números de línea en el texto de la clase. Sin embargo, hay una opción de número de línea en Eiffel Studio IDE, que se puede activar opcionalmente con fines de referencia (por ejemplo, programación de pares, etc.).
- ^ Barnes, D. y Kölling, M. Objetos primero con Java . "... la razón para usar esta construcción [esto] es que tenemos una situación que se conoce como sobrecarga de nombres - el mismo nombre se usa para dos entidades diferentes ... Es importante entender que los campos y los parámetros son variables separadas que existen independientemente unas de otras, aunque comparten nombres similares. Un parámetro y un campo que comparten un nombre no es realmente un problema en Java ". [ cita requerida ]
- ^ Crockford, Douglas, 2008. JavaScript: las buenas partes . O'Reilly Media Inc. y Yahoo! Inc. Capítulo 4, Funciones , p 28. ISBN 978-0-596-51774-8
- ^ Powell, Thomas A y Schneider, Fritz, 2012. JavaScript: La referencia completa, tercera edición. McGraw-Hill. Capítulo 5, Funciones , págs. 170–1. ISBN 978-0-07-174120-0
- ^ Goodman, Danny, con Morrison, Michael, 2004. Biblia JavaScript, 5ª edición. Wiley Publishing, Inc., Indianápolis, Estados Unidos. Capítulo 33, Funciones y objetos personalizados , p. 987. ISBN 0-7645-5743-2
- ^ https://www.lua.org/pil/16.html
- ^ msdn. "PowerShell: Acerca de las variables automáticas" . docs.microsoft.com . Consultado el 22 de marzo de 2018 .
- ^ msdn. "about_Classes" . docs.microsoft.com . Consultado el 17 de diciembre de 2018 .
- ^ Unificando tipos y clases en Python 2.2, Guido van Rossum, " Anulando el método __new__ "
Otras lecturas
- Meyers, Scott, 1995. C ++ más eficaz: 35 nuevas formas de mejorar sus programas y diseños . ISBN 0-201-63371-X Scott Meyers
- Stroustrup, Bjarne, 1994. El diseño y evolución de C ++ . Addison-Wesley Pub. Co. ISBN 0-201-54330-3 Bjarne Stroustrup