¿Quién conoce
JavaScript?

yo!
¿Quién sufre
JavaScript?


No uses JavaScript



🪦


A mi me encanta.
Os confieso que...

+50 nuevas
features
desde 2015...

¡Hey 👋!


https://midu.tube
https://midu.live

Miguel Ángel Durán


El JavaScript del futuro
¿Cómo evoluciona
JavaScript?
debe ser siempre
retrocompatible

y encima evitar...

Antes de 2015
EcmaScript
la receta para crear el lenguaje JavaScript
1995 - se empezó
1997 - se intentó
1998 - se progresó
xxxx - se abandonó por 10 años
2011 - se retomó
2015 - se tomó en serio

Personas expertas y altamente cualificadas de vendors

https://github.com/tc39/proposals
stage 0
stage 1
stage 2
stage 3
Las fases de una propuesta en JavaScript
💬 idea inicial
💡 propuesta
✍️ borrador
📝 candidato
y si no se 💀... entonces...




Nueva funcionalidad
que te va a salvar la vida

https://midu.link/js
¡Vota tus
favoritos!

Clonar Arrays y Objetos
Array y Objetos son referencias
const dynos = ['🦖', '🦕', '🐉']
const fakeCopyDynos = dynos
// cambio el valor del primer elemento en fakeCopyDynos
fakeCopyDynos[0] = '🐓'
// la copia tiene el cambio
console.log(fakeCopyDynos) // -> [ '🐓', '🦕', '🐉' ]
// pero si miramos también el contenido de dynos...
console.log(dynos) // -> [ '🐓', '🦕', '🐉' ]
// ¡sorpresa! nos han colado la 🐓
const dynos = ['🦖', '🦕', '🐉']
const fakeCopyDynos = dynos
console.log(dynos === fakeCopyDynos) // -> true
const arrayWithSameDynos = ['🦖', '🦕', '🐉']
console.log(dynos === arrayWithSameDynos) // -> false
Array y Objetos son referencias

WAT!!!!!!!1!!!
// Crear copias superficiales
const dynos = ['🦖', '🦕', '🐉']
const copyOfDynos = dynos.slice()
const dynos = ['🦖', '🦕', '🐉']
const copyOfDynos = [...dynos]
const dynos = ['🦖', '🦕', '🐉']
const copyOfDynos = Array.from(dynos)
Las copias superficiales son... superficiales...
const dynosAndFriends = ['🦖', '🦕', ['🦎', '🐊']]
const copy = [...dynosAndFriends]
// En el primer elemento del Array anidado ponemos una 🐓
copy[2][0] = '🐓'
// En la copia todo está bien
console.log(copy) // -> [ '🦖', '🦕', [ '🐓', '🐊' ] ]
// ¡Pero en nuestro Array original se ha cambiado también!
console.log(dynosAndFriends) // -> [ '🦖', '🦕', [ '🐓', '🐊' ] ]

"BASTA. DIME CÓMO ARREGLARLO"
JSON Hack
const dynosAndFriends = ['🦖', '🦕', ['🦎', '🐊']]
const dynosAndFriendsString = JSON.stringify(dynosAndFriends)
const copyOfDynosAndFriends = JSON.parse(dynosAndFriendsString)
// para one-liner-lovers 💛
const copyOfDynosAndFriends = JSON.parse(JSON.stringify(dynosAndFriends))


const dynosAndFriends = ['🦖', '🦕', ['🦎', '🐊']]
const cloneArray = items =>
items.map(item =>
Array.isArray(item)
? cloneArray(item)
: item
)
const copyOfDynosAndFriends = cloneArray(dynosAndFriends)
A manija...

import clone from 'just-clone'
let arr = [1, 2, 3]
let subObj = { aa: 1 }
let obj = { a: 3, b: 5, c: arr, d: subObj }
let objClone = clone(obj)
arr.push(4)
objClone.d.bb = 2
obj // {a: 3, b: 5, c: [1, 2, 3, 4], d: {aa: 1}}
objClone // {a: 3, b: 5, c: [1, 2, 3], d: {aa: 1, bb: 2}}
Con dependencias

Todas las soluciones previas tienen problemas
🏴☠️ Alguna un poco hacky
❌ Propensas a errores
🗓 Copias incompletas
🏋️♂️ Impactan la carga de JS

Ven... te enseñaré
a clonar objetos en JS

const dynosAndFriends = ['🦖', '🦕', ['🦎', '🐊']]
const clone = structuredClone(dynosAndFriends)
// En el primer elemento del Array anidado ponemos una 🐓
clone[2][0] = '🐓'
// En el clon está todo bien...
console.log(clone) // -> [ '🦖', '🦕', [ '🐓', '🐊' ] ]
// ¡Y el original sigue estando inalterado!
console.log(dynosAndFriends) // -> [ '🦖', '🦕', [ '🦎', '🐊' ] ]
structuredClone()
structuredClone()

¿Pero esto lo soporta
algún navegador?


structuredClone()

¡Vota tus
favoritos!


Esto no lo ha decidido el

WHATWG


Arrow functions
fetch()
Promises
Métodos de Array
structuredClone()
<img loading="lazy" />

WAT!!!!!!!1!!!
Grandes mejoras
en Arrays


Array Grouping
stage 3
const nums = [1, 2, 3, 4, 5]
// Agrupa los números en un objeto
// Pasándole la key donde debe añadirse
array.group((num, index, array) => {
return num % 2 === 0 ? 'even': 'odd'
})
// {
// odd: [1, 3, 5],
// even: [2, 4]
// }
Change
Array
by copy
stage 3
const sequence = [1, 2, 3]
const reversed = sequence.reverse()
reversed // => [3, 2, 1]
sequence // => [3, 2, 1]
// splice, sort...
Change
Array
by copy
stage 3
const sequence = [1, 2, 3]
sequence.toReversed() // => [3, 2, 1]
sequence // => [1, 2, 3]
const outOfOrder = [3, 2, 1]
outOfOrder.toSorted() // => [1, 2, 3]
outOfOrder // => [3, 1, 2]
const correctionNeeded = [1, 1, 3]
correctionNeeded.with(1, 2) // => [1, 2, 3]
correctionNeeded // => [1, 1, 3]
const input = [5, 4, 3, 2, 1, 0]
toSpliced(input, 2, 2) // [5, 4, 1, 0]
input // [5, 4, 3, 2, 1, 0]

+ programación
funcional

piping


output = input -> func1 -> func2 -> func3
const output = func3(func2(func1(input)))

const title = '3 Trucos de JavaScript'
const toLowerCase = (str) => str.toLowerCase()
const addHyphens = (str) => str.replace(/\s/g, '-')
const slug = addHyphens(toLowerCase(title))
console.log(slug) // -> 3-trucos-de-javascript
const pipe = (...args) => args.reduce((acc, el) => el(acc))
const slug = pipe(title, toLowerCase, addHyphens)
console.log(slug) // -> 3-trucos-de-javascript
Pipeline
Operator
stage 2
const title = '3 Trucos de JavaScript'
const toLowerCase = (str) => str.toLowerCase()
const addHyphens = (str) => str.replace(/\s/g, '-')
const output = title |> toLowerCase(%) |> addHyphens(%)
const output = title
|> toLoweCase(%)
|> addHyphens(%)
Pipeline
Operator
stage 2
// ahora...
return filter(obj, negate(cb(predicate)), context)
// en el futuro...
return cb(predicate)
|> negate(%)
|> filter(obj, %, context);
Pipeline
Operator
stage 2
console.log(
chalk.dim(
`$ ${Object.keys(envars)
.map(envar => `${envar}=${envars[envar]}`)
.join(' ')}`,
'node',
args.join(' ')
)
)
Pipeline
Operator
stage 2
Object.keys(envars)
.map(envar => `${envar}=${envars[envar]}`)
.join(' ')
|> `$ ${%}`
|> chalk.dim(%, 'node', args.join(' '))
|> console.log(%);
¡Nuevos tipos primitivos!

String, Number, Boolean,
null, undefined, BigInt, Symbol
Inmutables
Los que tenemos ahora...
const obj1 = { a: 'midu' }
const obj2 = { a: 'midu' }
obj1 === obj2 // false
const m = [1, 2, 3]
const n = [1, 2, 3]
m === n // false
Pero los objetos...
Records & Tuples
Records
& Tuples
stage 3
const r1 = #{ a: 'midu' }
const r2 = #{ a: 'midu' }
r1 === r2 // true
const t1 = #[1, 2, 3]
const t2 = #[1, 2, 3]
t1 === t2 // true
Records
& Tuples
stage 3
const persona = #{
name: 'Miguel',
aka: #['midudev', 'midu', 'midudog']
}
persona === #{
name: 'Miguel',
aka: #['midudev', 'midu', 'midudog']
} // -> true
¡Igualdad profunda!
#

Cositas a tener en cuenta
1. Sólo funciona
con tipos primitivos
Records
& Tuples
stage 3
const proposal = #{
id: 777,
title: "Propuesta Record & Tuple",
contents: `...`,
// Tuplas son primitivos,
// así que puedes usarlos
keywords: #[
"ecma",
"tc39",
"proposal",
"record",
"tuple"
],
};
✅
Records
& Tuples
stage 3
const chile = {
name: 'JSConf Chile',
puntuacion: 100
}
const conferencias = #[
chile, // TypeError
]
❌
2. Son inmutables
Records
& Tuples
stage 3
const persona = #{
name: 'Miguel',
aka: #['midudev', 'midu', 'midudog']
}
persona.name = 'Miguel Ángel'
// TypeError: Cannot assign to read
// only property 'name'
❌
Records
& Tuples
stage 3
const persona = #{
name: 'Miguel',
aka: #['midudev', 'midu', 'midudog']
}
const newPersona = #{
...persona,
name: 'Miguel Ángel'
}
console.log(newPersona)
✅
TypeScript
¿en JavaScript?



Type
Annotations
Type
Annotations
stage 1
let x: string
x = "hello"
x = 100
function equals(x: number, y: number): string {
return x === y
}
Básicamente
se ignoran los tipos
Y el futuro que
yo le veo a esto...
"
La experiencia del pasado, si no cae en el olvido, sirve de guía para el futuro.

La galleta de la fortuna
que me comí ayer
Temporal

let now = Temporal.Now.instant()
let checkDate = Temporal.PlainDate.from({
year: 2022,
month: 03,
day: 28
})
// Devuelve true al comparar fechas
Temporal.PlainDate.compare(now, checkDate)
// Y muchas más APIs...
Temporal
stage 3
Temporal
new Date()
🔪
💀
🤩
Vuestros votos...

Aprende JavaScript
gratis y de forma práctica
https://aprendejavascript.dev
¡Gracias!


https://midu.tube
https://midu.live

@midudev

El JavaScript del Futuro
By Miguel Angel Durán García
El JavaScript del Futuro
- 265