Esta página ha sido traducida del inglés por la comunidad.Aprende más y únete a la comunidad de MDN Web Docs.
this
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since julio de 2015.
Introducción
La palabra clavethis de una función se comporta un poco diferente en Javascript en comparación con otros lenguajes. Además tiene algunas diferencias entre elmodo estricto y el modo no estricto.
En general, el valor dethis 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étodobind() paraestablecer el valor de la funciónthis independientemente de como es llamada, y ES2015 introdujo lasfunciones flecha que no proporcionan su propio "binding" dethis (se mantiene el valor dethis del contexto léxico que envuelve a la función).
In this article
Pruébalo
const test = { prop: 42, func: function () { return this.prop; },};console.log(test.func());// Expected output: 42Sintaxis
this
Valor
El objeto contexto de JavaScript en el cual se está ejecutando el código actual.
Contexto global
En el contexto de ejecución global (fuera de cualquier función),this se refiere al objeto global, ya sea en modo estricto o no.
console.log(this.document === document); // true// En los navegadores web, el objeto window también es un objeto global:console.log(this === window); // truethis.a = 37;console.log(window.a); // 37Nota:Puedes obtener el objeto global usando la propieda globalglobalThis, no importa el contexto donde se ejecute esta propiedad, siempre hará referencia al objeto global.
Contexto de la función
Dentro de una función, el valor de this depende de cómo la función es llamada.
Llamada simple
function f1() { return this;}f1() === window; // objeto globalEn este caso, el valor dethis no está establecido por la llamada. Dado que el código no está en modo estricto, el valor de this debe ser siempre un objeto por lo que por defecto es el objeto global.
function f2() { "use strict"; // consultar modo estricto return this;}f2() === undefined;En modo estricto, el valor dethis 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 comonull o42 o "Yo no soy this".
Nota:En el segundo ejemplo,this debería serundefined, porquef2 fue llamado sin proporcionar ninguna base (ej.window.f2()). Esta característica no fue implementada en algunos navegadores cuando se comenzó a dar soporte almodo estricto. Como resultado, retorna incorrectamente el objeto window.
Como un método de un objeto
Cuando una función es llamada como un método de un objeto, elthis cambia por el metodo del objeto llamado.
En el siguiente ejemplo, cuandoo.f() es invocado, dentro de la funciónthis es ligado al objetoo.
var o = { prop: 37, f: function () { return this.prop; },};console.log(o.f()); // logs 37Note 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 elementof durante la definición deo. Sin embargo, podriamos haber definido con la misma facilidad la primera función y luego adjuntarlo ao.f. Hacerlo da como resultado el mismo comportamiento.
var o = { prop: 37 };function independent() { return this.prop;}o.f = independent;console.log(o.f()); // logs 37Esto demuestra que sólo importa que la función fue invocada del elementof deo.
Asimismo, el enlacethis 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 metodog del objetoo.b. Esta vez durante la ejecución,this dentro de la función se referirá ao.b. El hecho de que el objeto es en sí mismo un elemento deo no tiene ninguna consecuencia, la referencia más inmediata es todo lo que importa.
o.b = { g: independent, prop: 42 };console.log(o.b.g()); // logs 42... en la cadena de prototipo
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,this se referirá al objeto donde está el método de donde fue llamado. Como si ese método estuviera dentro del objeto.
var o = { f: function () { return this.a + this.b; },};var p = Object.create(o);p.a = 1;p.b = 4;console.log(p.f()); // 5En este ejemplo, el objeto asignado a la variablep no tiene su propia propiedadf, esto lo hereda de su prototipo. Pero no importa que la búsqueda def eventualmente encuentre un elemento con ese nombre eno; la búsqueda comenzó como una referencia ap.f, asithis dentro de la funcion toma el valor del objeto referido comop. Es decir, desde quef es llamado como método dep, suthis refiere ap. Esto es una interesante característica de la herencia de prototipo de JavaScript.
... o como un getter o setter
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 enlacethis al objeto desde el cual la propiedad esta siendo establecida u obtenida.
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.4142Como un constructor
Cuando una función es usada como un constructor (con la palabra clavenew), suthis 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.
/* * 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 37function C2() { this.a = 37; return { a: 38 };}o = new C2();console.log(o.a); // logs 38En el último ejemplo (C2), debido a que un objeto fue devuelto durante la construcción, el nuevo objeto que fue enlazado athis simplemente se descarta.( Esto esencialmente hace de la declaración "this.a = 37;" codigo muerto. No esta exactamente muerto,porque es ejecutado pero se puede eliminar sin efectos externos.)
call yapply
Cuando una función usa la plabra clavethis en su cuerpo, su valor puede ser enlazado a un objeto particular durante la ejecución del métodocall() orapply() que todas las funciones hereden deFunction.prototype.
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ónadd.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ónadd.apply(o, [10, 20]); // 1 + 3 + 10 + 20 = 34Funciones enlazadas
ECMAScript 5 introduceFunction.prototype.bind(). Llamando af.bind(someObject) crea una nueva función con el mismo cuerpo y alcance def, pero dondethis se produce en la función original, en la nueva función esto esta permanentemente ligado al primer argumento debind, independientemente de cómo la función está siendo utilizada.
function f() { return this.a;}var g = f.bind({ a: "azerty" });console.log(g()); // azertyvar o = { a: 37, f: f, g: g };console.log(o.f(), o.g()); // 37, azertyComo un controlador de eventos DOM
Cuando una función es usada como un controlador de eventos, suthis es cambiado desde el elemento del evento disparado (algunos navegadores no siguen esta convención para los listeners agregados dinámicamente con otros métodosaddEventListener).
// Cuando se llama como un listener, convierte en azul el elemento// relacionadofunction 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 documentovar elements = document.getElementsByTagName("*");// Añade bluify como un click listener asi cuando se hace click sobre el elemento,// este cambia a azulfor (var i = 0; i < elements.length; i++) { elements[i].addEventListener("click", bluify, false);}