Articulo de referencia

esto (programación informática)

`this` , `self` y `Me` son palabras clave que se utilizan en algunos lenguajes de programación para referirse al objeto, clase u otra entidad de la que forma parte el código que...

`this` , `self` y `Me` son palabras clave que se utilizan en algunos lenguajes de programación para referirse al objeto, clase u otra entidad de la que forma parte el código que se está ejecutando. La entidad a la que se hace referencia depende, por lo tanto, del contexto de ejecución (como el objeto cuyo método se llama). Los distintos lenguajes de programación utilizan estas palabras clave de maneras ligeramente diferentes. En los lenguajes donde una palabra clave como `this` es obligatoria, es la única forma de acceder a los datos y métodos almacenados en el objeto actual. Cuando son opcionales, estas palabras clave pueden diferenciar variables y funciones con el mismo nombre.this

Programación orientada a objetos

En muchos lenguajes de programación orientados a objetos , (también llamado o ) es una variable que se usa en métodos de instancia para referirse al objeto sobre el que están trabajando. El primer lenguaje OO, SIMULA 67 , usaba para referenciar explícitamente el 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 usan generalmente . Smalltalk y otros, como Object Pascal , Perl , Python , Ruby , Rust , Objective-C , DataFlex y Swift , usan . Visual Basic de Microsoft usa .thisselfMethisthisselfMe

El concepto es similar en todos los lenguajes: thissuele ser una referencia o puntero inmutable que apunta al objeto actual; este objeto suele ser el código que actúa como "padre" o "invocador" de la propiedad , método , subrutina o función que contiene la thispalabra clave. Una vez que un objeto se ha construido o instanciado correctamente, thissiempre es una referencia válida. Algunos lenguajes la requieren explícitamente; otros utilizan el ámbito léxico para usarla implícitamente y así hacer visibles los símbolos dentro de su clase. O, alternativamente, el objeto actual al que apunta thispuede ser un objeto de código independiente que ha llamado a la función o método que contiene la palabra clave this. Esto ocurre, 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 thisalmacenada en el espacio global fuera del objeto del documento; en ese contexto, thisapuntará al elemento de la página dentro del objeto del documento, no al objeto de la ventana que lo contiene. [ 2 ]

En algunos lenguajes, por ejemplo C++, Java y Raku, this`or` selfes 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 una referencia. Debe especificarse explícitamente. En Python y Perl, el parámetro no tiene por qué llamarse necesariamente this`or` 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 llama ` self. Rust requiere que el objeto `self` se llame &self`or` self, dependiendo de si la función invocada toma prestado el invocador o lo mueve, respectivamente.

Los métodos estáticos en C++ o Java no están asociados con instancias sino con clases, y por lo tanto no 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 clspara acceder al objeto de clase .

Sutilezas y dificultades

Cuando se utiliza el alcance léxico para inferir this, el uso de thisen el código, aunque no es ilegal, puede hacer sonar las alarmas a un programador de mantenimiento, aunque todavía hay usos legítimos de thisen este caso, como referirse 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 thisparámetro de puntero explícito. [ 3 ]

Recursión abierta

La semántica de despacho de this, es decir, que las llamadas a métodos en thisse despachan dinámicamente, se conoce como recursión abierta , y significa que estos métodos pueden ser sobrescritos por clases u objetos derivados. Por el contrario, la recursión con nombre directo o la recursión anónima de una función utiliza recursión cerrada , con despacho estático. Por ejemplo, en el siguiente código Perl para el factorial, el token __SUB__es una referencia a la función actual:

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

Por el contrario, en C++ (usando un explícito thispara mayor claridad, aunque no necesario) el thisenlace se realiza al objeto mismo, pero si el método de clase se declaró "virtual", es decir, polimórfico en la base, se resuelve mediante despacho dinámico para que las clases derivadas puedan sobrescribirlo.

factorial de entero sin signo ( entero sin signo n ) { if ( n == 0 ) { return 1 ; } else { return n * this -> factorial ( n - 1 ); } }

Este ejemplo es artificial, ya que se trata de una recursión directa, por lo que sobrescribir el factorialmétodo sobrescribirí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 recursión mutua. [ 4 ] [ 5 ]

El problema de la clase base frágil se ha atribuido a la recursión abierta, sugiriendo que la invocación de métodos por thisdefecto recursión cerrada (despacho estático) en lugar de recursión abierta (despacho dinámico), utilizando recursión abierta solo cuando se solicita específicamente; las llamadas externas (sin usar this) se despacharí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 cierta disciplina de programación; esta disciplina ha sido formalizada por C. Ruby y GT Leavens; consiste en las siguientes reglas: [ 8 ]

  • Ningún código invoca publicmétodos en this.
  • El código que se puede reutilizar internamente (mediante la invocación desde otros métodos de la misma clase) se encapsula en un método protectedo private; si también necesita exponerse directamente a los usuarios, entonces un publicmétodo contenedor llama al método interno.
  • La recomendación anterior puede flexibilizarse para los métodos puros .

Implementaciones

C++

Las primeras versiones de C++ permitían thiscambiar el puntero; al hacerlo, un programador podía cambiar el objeto sobre el que trabajaba un método. Esta característica se eliminó posteriormente, y ahora thisen C++ es un valor r . [ 9 ]

Las primeras versiones de C++ no incluían referencias y se ha sugerido que, de haberlas incluido desde el principio, habríathis sido una referencia, no un puntero. [ 10 ]

C++ permite que los objetos se autodestruyan con la instrucción de código fuente: delete this.

DO#

La palabra clave thisen C# funciona de la misma manera que en Java, para los tipos de referencia. Sin embargo, dentro de los tipos de valor de C# , thistiene una semántica bastante diferente, siendo similar a una referencia a una variable mutable ordinaria, e incluso puede aparecer en el lado izquierdo de una asignación.

Un uso de thisen C# es permitir la referencia a una variable de campo externa dentro de un método que contiene una variable local con el mismo nombre. En tal situación, por ejemplo, la instrucción var n = localAndFieldname;dentro del método asignará el tipo y el valor de la variable local localAndFieldnamea n, mientras que la instrucción var n = this.localAndFieldname;asignará el tipo y el valor de la variable de campo externa a n. [ 11 ]

D

En Dthis , un método de clase, estructura o unión hace referencia a una referencia inmutable de la instancia del agregado que lo contiene. Las clases son tipos de referencia , mientras que las estructuras y uniones son tipos de valor. En la primera versión de D, la palabra clave thisse usa como un 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.

Dylan

En el lenguaje de programación Dylan , que es un lenguaje orientado a objetos que admite multimétodos y no tiene el concepto de this, el envío de un mensaje a un objeto se mantiene en la sintaxis. Las dos formas que se muestran a continuación funcionan de la misma manera; las diferencias son solo azúcar sintáctico .

objeto.método(param1, param2)

y

método (objeto, parámetro1, parámetro2)

Eiffel

Dentro del texto de una 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 Currentpara hacer referencia a la clase actual y sus características. El uso de la palabra clave Currentes opcional, ya que Currentse sobreentiende simplemente al referirse abiertamente al nombre de la característica de la clase actual. Por ejemplo: Se podría tener una característica `foo` en una clase MY_CLASS y referirse a ella de la siguiente manera:

claseMI_CLASEfunción -- Accesofoo : ENTEROmi_función : ENTEROhacerResultado := foofinfin

[ 12 ]

La línea #10 (arriba) tiene la referencia implícita a Currenttravés de la llamada a simple `foo'.

La línea #10 (abajo) tiene la referencia explícita a Currenttravés de la llamada a `Current.foo'.

claseMI_CLASEfunción -- Accesofoo : ENTEROmi_función : ENTEROhacerResultado := Actual . foofinfin

Cualquiera de los dos enfoques es aceptable para el compilador, pero se prefiere la versión implícita (por ejemplo, ) ya que es menos verbosa.x := foo

Al igual que en otros idiomas, hay ocasiones en las que el uso de la palabra clave Currentes obligatorio, como por ejemplo:

claseMI_CLASEfunción -- Accesomi_comando-- Crear MY_OTHER_CLASS con `Current'localx : MI_OTRA_CLASEhacercrear x . hacer_con_algo ( Actual )finfin

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 thises una palabra clave del lenguaje Java que representa la instancia actual de la clase en la que aparece. Se utiliza para acceder a las variables y métodos de la clase.

Dado que todos los métodos de instancia son virtuales en Java, thisnunca pueden ser nulos. [ 13 ]

JavaScript

En JavaScript, que es un lenguaje de programación o scripting muy utilizado en los navegadores web, thises una palabra clave importante, aunque su significado depende del contexto en el que se utilice.

  • Cuando se usa fuera de cualquier función, en el espacio global, thisse refiere al objeto contenedor, que en este caso es la ventana del navegador contenedora, el windowobjeto.
  • Cuando se usa en una función definida en el espacio global, a qué thisse refiere la palabra clave depende de cómo se llama a la función. Cuando se llama a dicha función directamente (por ejemplo, f(x)), thisse 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 estricto, es undefined). Sin embargo, si se llama a una función global que contiene thiscomo parte del controlador de eventos de un elemento en el objeto del documento, thisse referirá al elemento HTML que realiza la llamada.
  • Cuando se llama a un método usando la newpalabra clave (por ejemplo, var c = new Thing()), entonces dentro de Thing thisse refiere al propio objeto Thing.
  • 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)), thisse referirá al objeto que contiene la función. [ 14 ] [ 15 ] Incluso es posible especificar manualmente thisal 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 sortear el significado diferente de thisen funciones anidadas como los manejadores de eventos DOM, es un modismo común en JavaScript guardar la thisreferencia del objeto que realiza la llamada en una variable (comúnmente llamada thato self), y luego usar la variable para referirse al objeto que realiza la llamada en funciones anidadas.

Por ejemplo:

// En este ejemplo, $ es una referencia a la biblioteca jQuery $ ( ".element" ). hover ( function () { // Aquí, tanto this como that apuntan al elemento bajo el cursor del ratón. var that = this ; $ ( this ). find ( '.elements' ). each ( function () { // Aquí, this apunta al elemento DOM que se está iterando. // Sin embargo, that todavía apunta al elemento bajo el cursor del ratón. $ ( this ). addClass ( "highlight" ); }); });

Cabe destacar que JavaScript utiliza tanto thisla palabra clave relacionada self[ 17 ] (a diferencia de la mayoría de los demás lenguajes que tienden a emplear una u otra), selfestando restringida específicamente a los web workers. [ 18 ]

Finalmente, como una forma confiable de hacer referencia específica al objeto global (ventana o equivalente), JavaScript cuenta con la globalThispalabra clave. [ 19 ]

Lua

En Lua, selfse crea como azúcar sintáctico cuando las funciones se definen usando el :operador. [ 20 ] Al invocar un método usando :, el objeto que se está indexando se dará implícitamente como el primer argumento de la función que se está invocando.

Por ejemplo, las dos funciones siguientes son equivalentes:

local obj = {}función obj.foo ( arg1 , arg2 ) print ( arg1 , arg2 ) -- no se puede usar "self" aquí finfunción obj : bar ( arg ) print ( self , arg ) -- "self" es un primer argumento implícito antes de arg end-- Todas las funciones pueden invocarse de ambas maneras, con "." o con ":"obj : foo ( "Foo" ) -- equivalente a obj.foo(obj, "Foo") obj . bar ( obj , "Bar" ) -- equivalente a obj:bar("Bar")

Lua en sí mismo no es orientado a objetos, pero cuando se combina con otra característica llamada metatablas, su uso selfpermite a los programadores definir funciones de una manera que se asemeja a la programación orientada a objetos.

PowerShell

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 todos los objetos 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, [ 22 ]$this la variable describe la instancia actual del objeto.

Pitón

En Python, no existe una palabra clave para ` this.`. Cuando se llama a una función miembro en un objeto, se invoca la función miembro con el mismo nombre en el objeto de clase, y este objeto se vincula automáticamente al primer argumento de la función. Por lo tanto, el primer parámetro obligatorio de los métodos de instancia actúa como this`.`; este parámetro se denomina convencionalmente ` self.`, pero puede tener cualquier nombre.

En los métodos de clase (creados con el classmethoddecorador), el primer argumento se refiere al objeto de clase en sí, y se denomina convencionalmente cls; estos se utilizan principalmente para constructores heredables, [ 23 ] donde el uso de la clase como parámetro permite crear subclases del constructor. En los métodos estáticos (creados con el staticmethoddecorador), no existe un primer argumento especial.

Óxido

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 selfcomo primer parámetro. Estas funciones se pueden llamar utilizando instance.method()azúcar sintáctico. Por ejemplo:

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

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. Las tres restantes aceptan un selfparámetro de diversas maneras y pueden llamarse en una Fooinstancia usando la sintaxis de notación de punto, que es equivalente a llamar al nombre de la función calificado por tipo con un selfprimer parámetro explícito.

let mut foo : Foo = Foo :: new (); // debe llamarse como una función especificada por tipo foo . refer (); // imprime "0". Foo::refer() tiene acceso de solo lectura a la instancia de foo foo . mutate ( 5 ); // modifica foo en su lugar, permitido por la especificación &mut, se necesita que foo esté declarado mut foo . consume (); // imprime "5" y destruye foo, ya que Foo::consume() toma posesión completa de self// equivalente a foo.refer() Foo :: refer ( foo ); // error de compilación: foo está fuera de ámbito

Ser

El idioma del yo recibe su nombre de este uso de "yo".

Xbase++

Selfse utiliza estrictamente dentro de los métodos de una clase. Otra forma de referirse a Selfes usar ::.

Véase también

Referencias

  1. Dahl, Ole Johan ; Myhrhaug, Bjørn; Nygaard, Kristen (1970). "Lenguaje base común, Centro de Computación de Noruega" .
  2. Powell, Thomas A. y Schneider, Fritz, 2012. JavaScript: The Complete Reference, Tercera edición. McGraw-Hill. Capítulo 11, Manejo de eventos , pág. 428. ISBN 978-0-07-174120-0
  3. Uso de la colección de compiladores GNU (GCC)Funciones miembro vinculadas
  4. " Recursión cerrada y abierta ", Ralf Hinze , julio de 2007
  5. Recursión abierta , Lambda, la herramienta definitiva
  6. " Recursión abierta selectiva: una solución al problema de la clase base frágil ", Jonathan Aldrich
  7. " Recursión abierta selectiva: una solución al problema de la clase base frágil ", Lambda the Ultimate
  8. Aldrich, Jonathan y Kevin Donnelly. « Recursión 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 la 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 .
  9. ISO/IEC 14882:2003(E): Lenguajes de programación - C++ . ISO/IEC. 2003.
  10. Stroustrup: Preguntas frecuentes sobre estilo y técnica de C++
  11. De Smet, Bart, 2011. C# 4.0 Unleashed. Sams Publishing, Indianápolis, EE. UU. Capítulo 4, Fundamentos del lenguaje , pág. 210. ISBN 978-0-672-33079-7
  12. NOTA: Los números de línea son solo para fines de referencia. Eiffel no incluye números de línea en el texto de la clase. Sin embargo, existe una opción para mostrar números de línea en el IDE Eiffel Studio, que se puede activar opcionalmente para fines de referencia (por ejemplo, programación en parejas, etc.).
  13. Barnes, D. y Kölling, M. Objects First with Java . "...la razón para usar esta construcción [this] es que tenemos una situación conocida 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 entre sí, aunque compartan nombres similares. Que un parámetro y un campo compartan un nombre no es un problema en Java."
  14. Crockford, Douglas, 2008. JavaScript: The Good Parts . O'Reilly Media Inc. y Yahoo! Inc. Capítulo 4, Funciones , pág. 28. ISBN 978-0-596-51774-8
  15. Powell, Thomas A. y Schneider, Fritz, 2012. JavaScript: The Complete Reference, Tercera edición. McGraw-Hill. Capítulo 5, Funciones , págs . 170-171 . ISBN 978-0-07-174120-0
  16. Goodman, Danny, con Morrison, Michael, 2004. JavaScript Bible, 5.ª edición. Wiley Publishing, Inc., Indianápolis, EE. UU. Capítulo 33, Funciones y objetos personalizados , pág. 987. ISBN 0-7645-5743-2
  17. Red de desarrolladores de Mozilla : Window.self
  18. Red de desarrolladores de Mozilla : API de Web Worker
  19. Red de desarrolladores de Mozilla : globalThis
  20. "Programación en Lua : 16" . 
  21. msdn. "PowerShell: Acerca de las variables automáticas" . docs.microsoft.com . Consultado el 22 de marzo de 2018 .
  22. msdn. "about_Classes" . docs.microsoft.com . Consultado el 17 de diciembre de 2018 .
  23. Unificación de tipos y clases en Python 2.2, Guido van Rossum, " Sobrescribiendo el método __new__ "

Lecturas adicionales

  • Meyers, Scott, 1995. C++ más eficaz: 35 nuevas formas de mejorar tus programas y diseños . ISBN 0-201-63371-XScott Meyers
  • Stroustrup, Bjarne, 1994. El diseño y la evolución de C++ . Addison-Wesley Pub. Co. ISBN 0-201-54330-3Bjarne Stroustrup