entendiendo esto, enlazar, llamar y aplicar en JavaScript

entendiendo esto, enlazar, llamar y aplicar en JavaScript

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.targeto event.currentTargetsegú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

calland applyare 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, como this sí sería undefined.

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 calland applyare 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.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *