diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
commit | 1109132f09d75da9a28b649c7677bb6ce07c40c0 (patch) | |
tree | 0dd8b084480983cf9f9680e8aedb92782a921b13 /files/es/web/javascript/referencia/operadores/this | |
parent | 4b1a9203c547c019fc5398082ae19a3f3d4c3efe (diff) | |
download | translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.gz translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.bz2 translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.zip |
initial commit
Diffstat (limited to 'files/es/web/javascript/referencia/operadores/this')
-rw-r--r-- | files/es/web/javascript/referencia/operadores/this/index.html | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/files/es/web/javascript/referencia/operadores/this/index.html b/files/es/web/javascript/referencia/operadores/this/index.html new file mode 100644 index 0000000000..74ed62bb60 --- /dev/null +++ b/files/es/web/javascript/referencia/operadores/this/index.html @@ -0,0 +1,239 @@ +--- +title: this +slug: Web/JavaScript/Referencia/Operadores/this +translation_of: Web/JavaScript/Reference/Operators/this +--- +<div>{{jsSidebar("Operators")}}</div> + +<h2 id="Introducción">Introducción</h2> + +<p>La palabra clave <strong><code>this</code></strong> de una función se comporta un poco diferente en Javascript en comparación con otros lenguajes. Además tiene algunas diferencias entre el <a href="/es/docs/Web/JavaScript/Referencia/Funciones/Modo_estricto" title="en-US/docs/JavaScript/Strict mode">modo estricto</a> y el modo no estricto.</p> + +<p>En general, el valor de <code>this</code> está determinado por cómo se invoca a la función. No puede ser establecida mediante una asignación en tiempo de ejecución, y puede ser diferente cada vez que la función es invocada. ES5 introdujo el método {{jsxref("Function.bind()", "bind()")}} para <a href="#Funciones_enlazadas" title="https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/Special/this#Bound_functions">establecer el valor de la función <code>this</code> independientemente de como es llamada</a>, y ES2015 introdujo las <a href="/es/docs/Web/JavaScript/Referencia/Funciones/Arrow_functions">funciones flecha</a> que no proporcionan su propio "binding" de <code>this</code> (se mantiene el valor de <code>this</code> del contexto léxico que envuelve a la función)</p> + +<p>{{EmbedInteractiveExample("pages/js/expressions-this.html")}}</p> + +<h2 id="Sintaxis">Sintaxis</h2> + +<pre class="syntaxbox">this</pre> + +<h3 id="Valor">Valor</h3> + +<p>El objeto contexto de JavaScript en el cual se está ejecutando el código actual.</p> + +<h2 id="Contexto_global">Contexto global</h2> + +<p>En el contexto de ejecución global (fuera de cualquier función), <strong><code>this</code></strong> se refiere al objeto global, ya sea en modo estricto o no.</p> + +<pre class="brush:js">console.log(this.document === document); // true + +// En los navegadores web, el objeto window también es un objeto global: +console.log(this === window); // true + +this.a = 37; +console.log(window.a); // 37 +</pre> + +<div class="blockIndicator note"> +<p><font><font>Nota: Puedes obtener el objeto global usando la propieda global <code>globalThis</code>, no importa el contexto donde se ejecute esta propiedad, siempre hará referencia al objeto global. </font></font></p> +</div> + +<h2 id="Contexto_de_la_función">Contexto de la función</h2> + +<p><span class="hps" style="line-height: 1.5;">Dentro de una</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">función</span><span style="line-height: 1.5;">, </span><span class="hps" style="line-height: 1.5;">el valor de this</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">depende de cómo</span><span style="line-height: 1.5;"> la función es l</span><span class="hps" style="line-height: 1.5;">lamada</span><span id="result_box" lang="es" style="line-height: 1.5;">.</span></p> + +<h3 id="Llamada_simple">Llamada simple</h3> + +<pre class="brush:js">function f1(){ + return this; +} + +f1() === window; // objeto global +</pre> + +<div><span class="hps" style="line-height: 1.5;">En</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">este caso</span><span style="line-height: 1.5;">,</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">el valor de <strong>this</strong></span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">no está establecido</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">por</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">la llamada</span><span style="line-height: 1.5;">.</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">Dado que el código</span><span style="line-height: 1.5;"> </span><span class="alt-edited hps" style="line-height: 1.5;">no está</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">en modo estricto</span><span style="line-height: 1.5;">, </span><span class="hps" style="line-height: 1.5;">el valor de this</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">debe ser siempre</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">un objeto</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">por lo que</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">por defecto es el</span><span style="line-height: 1.5;"> </span><span class="hps" style="line-height: 1.5;">objeto global</span><span style="line-height: 1.5;">.</span></div> + +<div></div> + +<div> +<pre class="brush:js" style="font-size: 14px;">function f2(){ + "use strict"; // consultar modo estricto + return this; +} + +f2() === undefined;</pre> +</div> + +<div><span style="line-height: 1.5;">En modo estricto, el valor de <strong>this</strong> se mantiene en lo que está establecida al entrar en el contexto de ejecución. Si no está definido, permanece undefined. También se puede ajustar a cualquier valor, tales como <strong>null</strong> o <strong>42</strong> o "<strong>Yo no soy this</strong>".</span></div> + +<div></div> + +<div class="note"> +<p><strong>Nota:</strong> En el segundo ejemplo, <strong><code>this</code></strong> debería ser {{jsxref("undefined")}}, porque <code>f2</code> fue llamado sin proporcionar ninguna base (ej. <code>window.f2()</code>). Esta característica no fue implementada en algunos navegadores cuando se comenzó a dar soporte al <a href="/es/docs/Web/JavaScript/Referencia/Funciones/Modo_estricto" title="Strict mode">modo estricto</a>. Como resultado, retorna incorrectamente el objeto window.</p> +</div> + +<div><span>Como un método de un objeto</span></div> + +<p>Cuando una función es llamada como un método de un objeto, el <strong><code>this</code></strong> cambia por el metodo del objeto llamado.</p> + +<p>En el siguiente ejemplo, cuando <strong><code>o.f()</code></strong> es invocado, dentro de la función <strong><code>this</code></strong> es ligado al objeto <strong><code>o</code></strong>.</p> + +<pre class="brush:js">var o = { + prop: 37, + f: function() { + return this.prop; + } +}; + +console.log(o.f()); // logs 37 +</pre> + +<p>Note que el comportamiento no es del todo afectado por cómo o dónde la función fue definida. En el ejemplo anterior, nosotros definimos la función en línea como el elemento <code>f</code> durante la definición de <code>o</code>. Sin embargo, podriamos haber definido con la misma facilidad la primera función y luego adjuntarlo a <code>o.f</code>. Hacerlo da como resultado el mismo comportamiento.</p> + +<pre class="brush:js">var o = {prop: 37}; + +function independent() { + return this.prop; +} + +o.f = independent; + +console.log(o.f()); // logs 37 +</pre> + +<p>Esto demuestra que sólo importa que la función fue invocada del elemento <code>f</code> de <code>o</code>.</p> + +<p>Asimismo, el enlace <code>this</code> sólo se ve afectado por la referencia del miembro más inmediata. En el siguiente ejemplo, cuando invocamos a la función, lo llamamos como metodo <code>g</code> del objeto <code>o.b</code>. Esta vez durante la ejecución, <code>this </code>dentro de la función se referirá a <code>o.b</code>. <span id="result_box" lang="es"><span class="hps">El hecho de que</span> <span class="hps">el objeto</span> <span class="hps">es en sí mismo</span> <span class="alt-edited hps">un elemento</span> <span class="hps">de </span></span><code>o</code><span id="result_box" lang="es"> <span class="hps">no tiene ninguna</span> <span class="hps">consecuencia</span><span>,</span> <span class="hps">la referencia más</span> <span class="hps">inmediata es</span> <span class="hps">todo lo que importa</span><span>.</span></span></p> + +<pre class="brush:js">o.b = {g: independent, prop: 42}; +console.log(o.b.g()); // logs 42 +</pre> + +<h4 id="..._en_la_cadena_de_prototipo">... en la cadena de prototipo</h4> + +<p>El mismo concepto es válido para los métodos definidos en alguna parte de la cadena de prototipo del objeto. Si el método esta sobre una cadena de prototipo del objeto, <code>this</code> se referirá al objeto donde está el método de donde fue llamado. Como si ese método estuviera dentro del objeto. </p> + +<pre class="brush:js">var o = {f:function(){ return this.a + this.b; }}; +var p = Object.create(o); +p.a = 1; +p.b = 4; + +console.log(p.f()); // 5 +</pre> + +<p>En este ejemplo, el objeto asignado a la variable <code>p</code> no tiene su propia propiedad <code>f</code>, esto lo hereda de su prototipo. Pero no importa que la búsqueda de <code>f</code> eventualmente encuentre un elemento con ese nombre en <code>o</code>; la búsqueda comenzó como una referencia a <code>p.f</code>, asi <code>this </code>dentro de la funcion toma el valor del objeto referido como <code>p</code>. Es decir, desde que <code>f</code> es llamado como método de <code>p</code>, su <code>this</code> refiere a <code>p</code>. Esto es una interesante característica de la herencia de prototipo de JavaScript.</p> + +<h4 id="..._o_como_un_getter_o_setter">... o como un getter o setter</h4> + +<p>Nuevamente, el mismo concepto es válido cuando una función es invocada de un getter o un setter. Una función usado como getter o setter tiene su enlace <code>this</code> al objeto desde el cual la propiedad esta siendo establecida u obtenida.</p> + +<pre class="brush:js">function modulus(){ + return Math.sqrt(this.re * this.re + this.im * this.im); +} + +var o = { + re: 1, + im: -1, + get phase(){ + return Math.atan2(this.im, this.re); + } +}; + +Object.defineProperty(o, 'modulus', {get: modulus, enumerable:true, configurable:true}); + +console.log(o.phase, o.modulus); // logs -0.78 1.4142 +</pre> + +<h3 id="Como_un_constructor">Como un constructor</h3> + +<p>Cuando una función es usada como un constructor (con la palabra clave {{jsxref("Operadores/new", "new")}}), su <code>this</code> es enlazado al nuevo objeto en construcción, a menos que la ejecución de los resultados del constructor en el motor JavaScript encuentren una instrucción de retorno donde el valor de retorno sea un objeto.</p> + +<pre class="brush:js">/* + * Los constructores trabajan algo asi: + * + * function MyConstructor(){ + * // El cuerpo del código de la función actual va aquí. Crear las propiedades en |this| como + * // se desee mediante la asignación a los mismos. E.g., + * this.fum = "nom"; + * // etcetera... + * + * // Si la función tiene una sentencia de retorno este retorna un objeto, + * // este objeto será el resultado de la expresión |new|. Por otro lado, el + * // resultado de la expresión es el objeto actualmente enlazado a |this| + * // (i.e., el caso más común suele verse). + * } + */ + +function C(){ + this.a = 37; +} + +var o = new C(); +console.log(o.a); // logs 37 + + +function C2(){ + this.a = 37; + return {a:38}; +} + +o = new C2(); +console.log(o.a); // logs 38 +</pre> + +<p>En el último ejemplo (<code>C2</code>), debido a que un objeto fue devuelto durante la construcción, el nuevo objeto que fue enlazado a <code>this</code> simplemente se descarta.( Esto esencialmente hace de la declaración "<code>this.a = 37;</code>" codigo muerto. No esta exactamente muerto,porque es ejecutado pero se puede eliminar sin efectos externos.)</p> + +<h3 id="call_y_apply"><code>call</code> y <code>apply</code></h3> + +<p>Cuando una función usa la plabra clave <code>this</code> en su cuerpo, su valor puede ser enlazado a un objeto particular durante la ejecución del método {{jsxref("Function.call()", "call()")}} or {{jsxref("Function.apply()", "apply()")}} que todas las funciones hereden de <code>Function.prototype</code>.</p> + +<pre class="brush:js">function add(c, d){ + return this.a + this.b + c + d; +} + +var o = {a:1, b:3}; + +// El primer parámetro es el objeto a usar como 'this', parámetros posteriores se pasan como argumentos +// en la llamada a la función +add.call(o, 5, 7); // 1 + 3 + 5 + 7 = 16 + +//El primer parámetro es el objeto a usar como 'this''this', la segunda es una matriz cuyos elementos +// se utilizan como argumentos en la llamada a la función +add.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34 +</pre> + +<h3 id="Funciones_enlazadas">Funciones enlazadas</h3> + +<p>ECMAScript 5 introduce {{jsxref("Function.prototype.bind()")}}. Llamando a <code>f.bind(someObject)</code> crea una nueva función con el mismo cuerpo y alcance de <code>f</code>, pero donde <code>this</code> se produce en la función original, en la nueva función esto esta permanentemente ligado al primer argumento de <code>bind</code>, independientemente de cómo la función está siendo utilizada.</p> + +<pre class="brush:js">function f(){ + return this.a; +} + +var g = f.bind({a:"azerty"}); +console.log(g()); // azerty + +var o = {a:37, f:f, g:g}; +console.log(o.f(), o.g()); // 37, azerty +</pre> + +<h3 id="Como_un_controlador_de_eventos_DOM">Como un controlador de eventos DOM</h3> + +<p>Cuando una función es usada como un controlador de eventos, su <code>this</code> es cambiado desde el elemento del evento disparado (algunos navegadores no siguen esta convención para los listeners agregados dinámicamente con otros métodos <code>addEventListener</code>).</p> + +<pre class="brush:js">// Cuando se llama como un listener, convierte en azul el elemento +// relacionado +function bluify(e){ + console.log(this === e.currentTarget); // Siempre true + console.log(this === e.target); // true cuando currentTarget y target son el mismo objeto + this.style.backgroundColor = '#A5D9F3'; +} + +// Consigue una lista de cada elemento en un documento +var elements = document.getElementsByTagName('*'); + +// Añade bluify como un click listener asi cuando se hace click sobre el elemento, +// este cambia a azul +for(var i=0 ; i<elements.length ; i++){ + elements[i].addEventListener('click', bluify, false); +}</pre> |