Este artículo fue escrito originalmente para DigitalOcean.
la palabra clave this
es un concepto muy importante en JavaScript, y también particularmente confuso tanto para los nuevos desarrolladores como para aquellos que tienen experiencia en otros lenguajes de programación. En JavaScript, this
es una referencia a un objeto., El objeto al que se refiere this
puede variar, implícitamente en función de si es global, en un objeto o en un constructor, y también puede variar explícitamente en función del uso de los métodos prototipo Function
bind
, call
, y apply
.
aunque this
es un tema un poco complejo, también es uno que aparece tan pronto como comienza a escribir sus primeros programas JavaScript., Ya sea que esté intentando acceder a un elemento o evento en el modelo de objetos de documento (DOM), creando clases para escribir en el estilo de programación orientada a objetos o utilizando las propiedades y métodos de objetos regulares, encontrará this
.
en este artículo, aprenderá a qué se refiere this
implícitamente basado en el contexto, y aprenderá cómo usar los métodos bind
, call
y apply
para determinar explícitamente el valor de this
.,
contexto implícito
Hay cuatro contextos principales en los que el valor de this
puede inferirse implícitamente:
- El contexto global
- Como un método dentro de un objeto
- Como un constructor en una función o clase
- Como un controlador de eventos DOM
Global
en el contexto global, this
se refiere al objeto global. Cuando está trabajando en un navegador, el contexto global es window
. Cuando estás trabajando en Node.js, el contexto global es global
.,
Nota: Si aún no está familiarizado con el concepto de alcance en JavaScript, Revise comprender las Variables, el alcance y la elevación en JavaScript.
para los ejemplos, practicará el código en la consola de herramientas para desarrolladores del navegador. Lea Cómo Usar la consola de desarrolladores de JavaScript si no está familiarizado con la ejecución de código JavaScript en el navegador.
Si usted registra el valor de this
sin ningún otro código, verás qué objeto this
se refiere.,
console.log(this)
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
Usted puede ver que el this
es window
, que es el objeto global de un navegador.
al comprender las Variables, el alcance y la elevación en JavaScript, aprendió que las funciones tienen su propio contexto para las variables. Puede estar tentado a pensar que this
seguiría las mismas reglas dentro de una función, pero no lo hace. Una función de nivel superior conservará la referencia this
del objeto global.,
escribir una función de nivel superior, o una función que no está asociado con ningún objeto, como este:
function printThis() { console.log(this)}printThis()
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
Incluso dentro de una función, this
todavía se refiere a la etiqueta window
, o de objeto global.
sin Embargo, cuando se utiliza el modo estricto, el contexto de this
dentro de una función en el contexto global será undefined
.,
'use strict'function printThis() { console.log(this)}printThis()
undefined
por lo General, es más seguro utilizar el modo estricto para reducir la probabilidad de this
tener un inesperado alcance. Rara vez alguien querrá referirse al objeto window
usando this
.
para obtener más información sobre el modo estricto y los cambios que realiza con respecto a los errores y la seguridad, lea la documentación del modo estricto en MDN.,
Un Método de Objeto
Un método es una función de un objeto, o una tarea que un objeto puede realizar. Un método utiliza this
para referirse a las propiedades del objeto.
"The United States of America was founded in 1776."
En este ejemplo, this
es el mismo america
.
en un objeto anidado, this
se refiere al ámbito de objeto actual del método. En el siguiente ejemplo, this.symbol
dentro de la etiqueta details
objeto se refiere a details.symbol
.,
"The symbol is the eagle and the currency is USD."
otra forma de pensar es que this
se refiere al objeto en el lado izquierdo del punto cuando se llama a un método.
un Constructor de función
Cuando utiliza la palabra clave new
, crea una instancia de una función o clase constructora. Los constructores de funciones eran la forma estándar de inicializar un objeto definido por el Usuario antes de que se introdujera la sintaxis class
en la actualización de ECMAScript 2015 a JavaScript., En comprensión de clases en JavaScript, aprenderá cómo crear un constructor de función y un constructor de clase equivalente.
"The United States of America was founded in 1776."
En este contexto, this
está vinculado a la instancia de Country
, que se encuentra en el america
constante.
un Constructor de clase
un constructor en una clase actúa de la misma manera que un constructor en una función. Obtenga más información sobre las similitudes y diferencias entre los constructores de funciones y las clases ES6 en comprensión de clases en JavaScript.,
this
en el describe
método se refiere a la instancia de Country
que es america
.
"The United States of America was founded in 1776."
un controlador de eventos DOM
en el navegador, hay un contexto especial this
para los controladores de eventos. En un controlador de eventos llamados por addEventListener
, this
se refieren a event.currentTarget
., La mayoría de las veces, los desarrolladores simplemente usarán event.target
o event.currentTarget
según sea necesario para acceder a los elementos en el DOM, pero como la referencia this
cambia en este contexto, es importante saberlo.
en el siguiente ejemplo, crearemos un botón, le agregaremos texto y lo agregaremos al DOM. Cuando registramos el valor de this
dentro del controlador de eventos, imprimirá el destino.,
<button>Click me</button>
Una vez que pegue esto en su navegador, verá un botón agregado a la página que dice»Haga clic en mí». Si hace clic en el botón, verá que <button>Click me</button>
aparece en su consola, ya que al hacer clic en el botón se registra el elemento, que es el botón en sí. Por lo tanto, como puede ver, this
se refiere al elemento objetivo, que es el elemento al que agregamos un detector de eventos.,
Explicit Context
en todos los ejemplos anteriores, el valor de this
estaba determinado por su contexto, ya sea global, en un objeto, en una función o clase construida, o en un controlador de eventos DOM. Sin embargo, el uso de call
, apply
o bind
, se puede determinar explícitamente lo this
debe referirse.,
es difícil definir exactamente cuándo usar call
, apply
o bind
, ya que dependerá del contexto de su programa. bind
puede ser particularmente útil cuando desea usar eventos para acceder a las propiedades de una clase dentro de otra clase. Por ejemplo, si escribiera un juego simple, podría separar la interfaz de usuario y la E/s en una clase, y la lógica y el estado del juego en otra., Dado que la lógica del juego tendría que acceder a la entrada, como presionar una tecla y hacer clic, querrá bind
los eventos para acceder al valor this
de la clase lógica del juego.
la parte importante es saber cómo determinar a qué objeto this
se refiere, lo que puede hacer implícitamente con lo que aprendió en las secciones anteriores, o explícitamente con los tres métodos que aprenderá a continuación.,
Call and Apply
call
and apply
are very similar—they invoke a function with a specified this
context, and optional arguments. La única diferencia entre call
y apply
es que call
requiere de los argumentos que se pasan de uno-por-uno, y apply
tiene los argumentos como una matriz.,
en este ejemplo, crearemos un objeto y crearemos una función que haga referencia a this
pero no tenga un contexto this
.
"undefined was written by undefined"
Desde summary
y book
no tienen ninguna conexión, invocando summary
por sí mismo sólo se imprime undefined
, ya que se busca que esas propiedades en el objeto global.,
Nota: Intentar esto en modo estricto sería el resultado en el
Uncaught TypeError: Cannot read property 'title' of undefined
, comothis
sí seríaundefined
.
sin Embargo, puede usar call
y apply
para invocar el this
contexto book
en la función.,
summary.call(book)// or:summary.apply(book)
"Brave New World was written by Aldous Huxley."
ahora Hay una conexión entre book
y summary
cuando estos métodos se aplican. Confirmemos exactamente qué es this
.
function printThis() { console.log(this)}printThis.call(book)// or:whatIsThis.apply(book)
{title: "Brave New World", author: "Aldous Huxley"}
En este caso, this
en realidad se convierte en el objeto pasado como argumento.
así es como call
y apply
son lo mismo, pero hay una pequeña diferencia., Además de poder pasar el contexto this
como primer argumento, también puede pasar argumentos adicionales.
function longerSummary(genre, year) { console.log( `${this.title} was written by ${this.author}. It is a ${genre} novel written in ${year}.`, )}
Con la etiqueta call
cada valor adicional que desee pasar es enviado como un argumento adicional.,
longerSummary.call(book, 'dystopian', 1932)
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
Si usted intenta enviar exactamente los mismos argumentos con la etiqueta apply
, esto es lo que sucede:
longerSummary.apply(book, 'dystopian', 1932)
Uncaught TypeError: CreateListFromArrayLike called on non-object at <anonymous>:1:15
en su Lugar, para apply
, usted tiene que pasar todos los argumentos en una matriz.
longerSummary.apply(book, )
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
La diferencia entre pasar los argumentos de forma individual o en una matriz es sutil, pero es importante ser consciente de., Podría ser más simple y más conveniente usar apply
, ya que no requeriría cambiar la llamada a la función si cambiaran algunos detalles de los parámetros.
Bind
Both call
and apply
are one-time use methods—if you call the method with the this
context it will have it, but the original function will remain unchanged.,
a veces, es posible que necesite usar un método una y otra vez con el contexto this
de otro objeto, y en ese caso podría usar el método bind
para crear una función nueva con un enlace explícito this
.
const braveNewWorldSummary = summary.bind(book)braveNewWorldSummary()
"Brave New World was written by Aldous Huxley"
En este ejemplo, cada vez que se llama braveNewWorldSummary
, siempre devolverá el original this
valor enlazado a él., Intentar enlazar un nuevo contexto this
fallará, por lo que siempre puede confiar en que una función enlazada devolverá el valor this
que espera.
aunque este ejemplo intenta enlazar braveNewWorldSummary
una vez más, conserva el contexto original this
desde la primera vez que fue enlazado.
funciones de flecha
Las funciones de flecha no tienen su propio this
binding. En cambio, pasan al siguiente nivel de ejecución.,
Puede ser útil usar la función arrow en los casos en los que realmente desee this
para referirse al contexto externo. Por ejemplo, si tiene un detector de eventos dentro de una clase, probablemente querrá que this
se refiera a algún valor en la clase.
en este ejemplo, crearás y agregarás el botón al DOM como antes, pero la clase tendrá un receptor de eventos que cambiará el valor de texto del botón cuando se haga clic.
si hace clic en el botón, el contenido del texto cambiará al valor de buttonText
., Si no hubiera usado una función de flecha aquí, this
sería igual a event.currentTarget
, y no podría usarla para acceder a un valor dentro de la clase sin vincularlo explícitamente. Esta táctica se usa a menudo en métodos de clase en marcos como React.
conclusión
en este artículo, aprendiste sobre this
en JavaScript, y los muchos valores diferentes que podría tener basado en el enlace implícito en tiempo de ejecución, y el enlace explícito a través de bind
, call
, y apply
., También aprendió sobre cómo la falta dethis
enlace en las funciones de flecha se puede utilizar para referirse a un contexto diferente. Con este conocimiento, debería ser capaz de determinar el valor de this
en sus programas.