Guías de Make it Real
  • Introduction
  • Preparación
    • Conceptos básicos
    • El editor de texto
    • La línea de comandos
    • Git y Github
  • Git
    • Instalación y configuración
    • Conceptos y comandos esenciales
    • Ignorando archivos y carpetas
    • Trabajando con ramas
    • Repositorios remotos
    • Etiquetas
    • Reescribiendo la historia
    • Stashing
    • Github
  • HTML y CSS
    • Introducción a HTML
    • Introducción a CSS
    • Más elementos de HTML
    • Tablas
    • Formularios
    • El modelo de caja en CSS
    • Fondos (backgrounds)
    • Posicionamiento
    • Selectores CSS
    • Bordes, sombras y gradientes
    • Media Queries
    • Unidades en CSS
    • Flexbox
  • Bootstrap 3
    • Primeros pasos
    • Elementos básicos de HTML
    • Componentes
    • La grilla
    • Personalizando Bootstrap
    • Utilizando plantillas
  • Bootstrap 4
    • Primeros pasos
    • Elementos básicos de HTML
    • Componentes
    • La grilla
    • Clases utilitarias
    • Personalizando Bootstrap
  • Ruby
    • Primeros pasos
    • Tipos y operadores
    • Variables y entrada de usuario
    • Condicionales
    • Ciclos
    • Arreglos
    • Más cadenas de texto
    • Hashes
    • Métodos
    • Manipulación de archivos
    • Gemas
  • Programación Orientada a Objetos en Ruby
    • Clases y objetos
    • Métodos y atributos de clase
    • Herencia
    • Módulos
    • Excepciones
  • JavaScript I
    • Primeros pasos
    • Tipos y operadores
    • Variables
    • Condicionales
    • Ciclos
    • Arreglos
    • Más cadenas de texto
    • Funciones
    • Objetos literales
    • Manipulación de archivos
  • JavaScript en el navegador
    • Primeros pasos
    • Manipulando HTML
    • Escuchando eventos
    • Local Storage
    • History API
    • Canvas
    • Notificaciones Web
    • Audio y Video
    • Arrastrar y soltar
    • JSON
    • Realizando peticiones HTTP
  • jQuery
    • Primeros pasos
    • Manipulando HTML
    • Escuchando eventos
    • Plugins
    • Realizando peticiones con AJAX
  • JavaScript II
    • Prototipos
    • Librerías (Node.js)
    • ES6
    • Uso de this (call, apply, bind)
    • Programación funcional
    • Scope, hoisting, closures
    • Programación asincrónica
    • Testing
  • HTTP y Sinatra
    • Primeros pasos con Sinatra
    • El protocolo HTTP
    • Rutas
    • Formularios
    • Cookies y sesión
  • Bases de datos
    • Bases de datos relacionales
    • SQL
    • DDL
    • MongoDB
  • Ruby on Rails I
    • Primeros pasos
    • Arquitectura
    • Rutas
    • Layouts y rendering
    • ActiveRecord - Modelos
    • ActiveRecord - Migraciones
    • ActiveRecord - Validaciones
    • ActiveRecord - Asociaciones
    • ActiveRecord - Scopes
    • ActiveRecord - Callbacks
    • Recursos REST
    • Formularios
    • Autenticación con Devise
    • Sass y Bootstrap
    • Envío de correos
    • Carga de imágenes
    • Seeds
    • Heroku
  • Ruby on Rails II
    • Usando JavaScript (y jQuery) en Rails
    • Testing en Ruby
    • Testing en Rails
    • Creando una Web API
    • Web Sockets
  • Express.js
    • Primeros Pasos
    • El protocolo HTTP
    • Rutas
    • Vistas
    • Middlewares y manejo de errores
    • Formularios
    • Cookies y sesión
  • Express.js II
    • Mongoose
    • Web Sockets
    • Autenticación
    • Envío de correos
    • Cargar imágenes
    • Deployment
    • Testing
    • Creando una Web API
  • React
    • Primeros pasos
    • JSX
    • Componentes
    • Más sobre estado
    • Formularios
    • Peticiones HTTP con Axios
    • React Hooks
    • React Context
    • React Bootstrap
    • React Router
    • Carga de Imágenes
    • Testing
    • Estructura de carpetas
    • Componentes de clase
  • Redux
    • Primeros pasos
    • Action creators
    • Usando la librería react-redux
    • Middlewares
    • Operaciones asincrónicas con redux-thunk
    • Combinando funciones reductoras
    • Testing
    • Redux Tool Kit
  • Algoritmos
    • Describiendo un algoritmo
    • Complejidad (Big-O)
    • Estructuras de datos
    • Recursión
    • Ordenamiento
    • Búsqueda
    • Programación dinámica
  • Python
    • Primeros Pasos
    • Tipos y Variables
    • Funciones
    • Control de Flujo
    • Listas
    • Ciclos
    • Diccionarios, Tuplas y Sets
  • NumPy
    • Primeros Pasos
    • Arreglos
    • Arreglos Multidimensionales
    • Estadística con NumPy
    • Distribución Estadística
  • Pandas
    • Primeros Pasos
    • Inspección y Selección de Datos
    • Modificando Dataframes
    • La Función Lambda
    • Aggregates en Pandas
    • Múltiples Tablas
Powered by GitBook
On this page
  • Diferentes contextos para this
  • call y apply
  • bind
  • Funciones flecha
  1. JavaScript II

Uso de this (call, apply, bind)

this es una palabra clave en JavaScript que se utiliza para referirnos a las propiedades de un objeto. Por ejemplo:

const person = {
  name: "Pedro",
  greet() {
    console.log(`Hola ${this.name}`)
  }
}

La única forma de referirnos a la propiedad name desde el método greet es utilizando la palabra clave this:

person.greet() // "Hola Pedro"

Diferentes contextos para this

El problema con this es que las funciones en JavaScript se pueden mover de un lado a otro: se pueden asignar a variables, pasar como argumento de otra función y retornar desde otra función. La pregunta es qué le pasa a this cuando ocurre todo este movimiento.

Por ejemplo, ¿qué pasa si asignamos el método greet del objeto person (ejemplo anterior) a una nueva variable hello?

const hello = person.greet
hello() // "Hola undefined"

En JavaScript, this cambia según el lugar desde el que se invoque:

  • Si se invoca sobre el método de un objeto, this se refiere a las propiedades del objeto (el caso normal).

  • Si se invoca afuera de un objeto, this se refiere al contexto global (el objeto window en un navegador o undefined en Node.js).

  • Si se invoca sobre una función constructora, this se refiere al nuevo objeto creado.

Hay otra forma de cambiar el contexto de this y es con los métodos call y apply.

call y apply

Estos dos métodos nos permiten cambiar el contexto del this al invocar una función. Por ejemplo, imagina que tenemos una función llamada greet que utiliza this internamente, podemos utilizar call para cambiar el contexto de this al invocarla:

const greet = function() {
  console.log(`Hola ${this.name}`)
}

const pedro = { name: "Pedro" }
greet.call(pedro) // "Hola Pedro"

const maria = { name: "Maria" }
greet.call(maria) // "Hola Maria"

La diferencia entre call y apply es la forma en que se pasan los argumentos de la función: apply recibe los argumentos como un arreglo, mientras que call los recibe como argumentos independientes. Por ejemplo:

const sum = function(a, b) {
  console.log(`${this.name}, el resultado es ${a + b}`)
}

const pedro = { name: "Pedro" }
sum.call(pedro, 1, 2) // "Pedro, el resultado es 3"
sum.apply(pedro, [1, 2]) // "Pedro, el resultado es 3"

bind

Con el método bind podemos garantizar que un método siempre se invoque en un contexto específico. Por ejemplo:

let greet = function() {
  console.log(`Hola ${this.name}`)
}

const pedro = { name: "Pedro" }
greet = greet.bind(pedro); // sobrescribimos la variable

greet() // "Hola Pedro"

El método bind devuelve una nueva función que encapsula a la original para garantizar que siempre se ejecute con el contexto que queremos. En este ejemplo estamos sobrescribiendo la variable greet pero hubiésemos podido asignarla a una variable diferente.

Funciones flecha

Las funciones flecha, a diferencia de las funciones normales, mantienen siempre el contexto de this enlazado al lugar donde son defininidas, independiente de cómo se llamen. Veamos un ejemplo.

Podemos modificar el método greet para que imprima el saludo después de 1 segundo utilizando la función setTimeout, que nos permite ejecutar una función después del tiempo que le digamos:

const person = {
  name: "Pedro",
  greet() {
    setTimeout(function() {
      console.log(`Hola ${this.name}`)
    }, 1000)
  }
}

El problema es que si ahora ejecutamos el método greet obtendremos un resultado inesperado:

person.greet();
// después de 1 segundo imprime "Hola undefined"

La razón es que internamente setTimeout invoca la función desde el contexto global y por lo tanto la referencia original de this se pierde.

Cuando no existían las funciones flecha, la única solución era asignar this a una variable con otro nombre:

greet() {
  const self = this; // guardamos this en otra variable self
  setTimeout(function() {
    console.log(`Hola ${self.name}`) // utilizamos self en vez de this
  }, 1000)
}

Hoy podemos utilizar funciones flecha que mantienen el contexto de this enlazado al lugar donde se definió:

greet() {
  setTimeout(() => { // función flecha
    console.log(`Hola ${this.name}`)
  }, 1000)
}

En este caso la función flecha se definió dentro del método greet, cuyo contexto es el objeto person.

PreviousES6NextProgramación funcional

Last updated 2 years ago