0% encontró este documento útil (0 votos)
173 vistas

Reintroducción a JavaScript (Tutorial de JS) -- 16 pp

JavaScript, creado en 1995 por Brendan Eich, es un lenguaje de programación dinámico y multiparadigma que ha evolucionado significativamente desde su lanzamiento, siendo fundamental para el desarrollo web moderno. A diferencia de otros lenguajes, JavaScript no tiene un concepto de entrada o salida y se ejecuta en entornos hospedados, como navegadores y servidores. El documento proporciona una visión general de sus características, tipos de datos, operadores y estructuras de control, destacando su importancia y versatilidad en la programación.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
173 vistas

Reintroducción a JavaScript (Tutorial de JS) -- 16 pp

JavaScript, creado en 1995 por Brendan Eich, es un lenguaje de programación dinámico y multiparadigma que ha evolucionado significativamente desde su lanzamiento, siendo fundamental para el desarrollo web moderno. A diferencia de otros lenguajes, JavaScript no tiene un concepto de entrada o salida y se ejecuta en entornos hospedados, como navegadores y servidores. El documento proporciona una visión general de sus características, tipos de datos, operadores y estructuras de control, destacando su importancia y versatilidad en la programación.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 16

Esta página fue traducida del inglés por la comunidad, pero no se mantiene activamente, por lo que puede estar

desactualizada. Si desea ayudar


a mantenerlo, descubra cómo activar las configuraciones regionales inactivas.

Una reintroducción a JavaScript (Tutorial de JS)


¿Por qué una reintroducción? Porque JavaScript es conocido por ser
el lenguaje de programación más incomprendido . A menudo se le ridiculiza como un juguete, pero
debajo de esa capa de engañosa simplicidad, aguardan poderosas características del lenguaje. Ahora un
increíble número de aplicaciones de alto perfil utilizan JavaScript, lo cual demuestra que un conocimiento
más profundo de esta tecnología es una habilidad importante para cualquier desarrollador web o móvil.

Es útil comenzar con una descripción general de la historia del lenguaje. JavaScript fue creado en 1995
por Brendan Eich mientras era ingeniero en Netscape. JavaScript se lanzó por primera vez con Netscape 2
a principios de 1996. Originalmente se iba a llamar LiveScript, pero se le cambió el nombre en una
desafortunada decisión de marketing que intentó capitalizar la popularidad del lenguaje Java de Sun
Microsystem, a pesar de que los dos tienen muy poco en común. Esto ha sido una fuente de confusión
desde entonces.

Varios meses después, Microsoft lanzó JScript con Internet Explorer 3. Era un JavaScript prácticamente
compatible. Varios meses después de eso, Netscape envió JavaScript a Ecma International , una
organización europea de estándares, que resultó en la primera edición del estándar ECMAScript ese año.
El estándar recibió una actualización significativa como ECMAScript edición 3 en 1999, y se ha
mantenido bastante estable desde entonces. La cuarta edición fue abandonada debido a diferencias
políticas sobre la complejidad del lenguaje. Muchas partes de la cuarta edición formaron la base para la
edición 5 de ECMAScript, publicada en diciembre de 2009, y para la sexta edición principal del estándar,
publicada en junio de 2015.

Debido a que es más familiar, nos referiremos a ECMAScript como "JavaScript" de ahora en adelante.

A diferencia de la mayoría de los lenguajes de programación, el lenguaje JavaScript no tiene un concepto


de entrada o salida. Está diseñado para ejecutarse como un lenguaje de scripting en un entorno
hospedado, y depende del entorno para proporcionar los mecanismos para comunicarse con el mundo
exterior. El entorno de alojamiento más común es el navegador, pero también se pueden encontrar
intérpretes de JavaScript en una gran lista de otros lugares, incluidos Adobe Acrobat, Adobe Photoshop,
imágenes SVG, el motor de widgets de Yahoo, entornos de lado del servidor como Node.js , bases de
datos NoSQL como Apache CouchDB de código abierto, computadoras integradas, entornos de
escritorio completos como GNOME (una de las IGU —Interfaz Gráfica de Usuario— más populares para
sistemas operativos GNU/Linux), y otros.

Información general
JavaScript es un lenguaje dinámico múltiparadigma con tipos y operadores, objetos estándar integrados y
métodos. Su sintaxis se basa en los lenguajes Java y C — muchas estructuras de esos lenguajes también
se aplican a JavaScript. JavaScript admite la programación orientada a objetos con prototipos de objetos,
en lugar de clases (consulta más información sobre herencia prototípica y ES2015 clases .
JavaScript también admite la programación funcional — debido a que son objetos, las funciones se
pueden almacenar en variables y pasarse como cualquier otro objeto.

Comencemos observando los componentes básicos de cualquier lenguaje: los tipos. Los programas
JavaScript manipulan valores, y todos esos valores pertenecen a un tipo. Los tipos de JavaScript son:

Números

Cadenas de texto (Strings)

Booleanos
Funciones

Objetos
Símbolos (nuevo en ES2015)

... oh, y undefined y null , que son ... ligeramente extraños. Y Array , que es un tipo de objeto especial.
Y Fechas (Date) y Expresiones regulares (RegExp) , que son objetos que obtienes de forma
gratuita. Y para ser técnicamente precisos, las funciones son solo un tipo especial de objeto. Por lo tanto,
el diagrama de tipos se parece más a este:

Números
Cadenas de texto (Strings)

Booleanos

Símbolos (nuevo en ES2015)


Objetos
Funciones

Array
Date

RegExp

null

undefined

Y también hay algunos tipos Error integrados. Sin embargo, las cosas son mucho más fáciles si nos
atenemos al primer diagrama, por lo que discutiremos los tipos enumerados allí por ahora.

Números
Los números en JavaScript son "valores IEEE 754 de formato de 64 bits de doble precisión", de acuerdo
con las especificaciones. No existen números enteros en JavaScript (excepto BigInt ), por lo que debes
tener un poco de cuidado. Ve este ejemplo:

console.log(3 / 2); // 1.5, not 1


console.log(Math.floor(3 / 2)); // 1

Entonces, un entero aparente de hecho implícitamente es un float .

Además, ten cuidado con cosas como:

0.1 + 0.2 == 0.30000000000000004;

En la práctica, los valores enteros se tratan como enteros de 32 bits, y algunas implementaciones incluso
los almacenan de esa manera hasta que se les pide que realicen una instrucción que sea válida en un
Número pero no en un entero de 32 bits. Esto puede ser importante para operaciones bit a bit.

Se admiten los operadores estándar, incluidas la aritmética de suma, resta, módulo (o resto), etc.
También hay un objeto incorporado que no mencionamos anteriormente llamado Math que proporciona
funciones matemáticas avanzadas y constantes:

Math.sin(3.5);
var circumference = 2 * Math.PI * r;

Puedes convertir una cadena en un número entero usando la función parseInt() incorporada. Esta toma
la base para la conversión como un segundo argumento opcional, que siempre debes proporcionar:

parseInt('123', 10); // 123


parseInt('010', 10); // 10

En los navegadores más antiguos, se supone que las cadenas que comienzan con un "0" están en octal
(raíz 8), pero este no ha sido el caso desde 2013 más o menos. A menos que estés seguro de tu formato
de cadena, puedes obtener resultados sorprendentes en esos navegadores más antiguos:

parseInt('010'); // 8
parseInt('0x10'); // 16

Aquí, vemos que la función parseInt() trata la primera cadena como octal debido al 0 inicial, y la
segunda cadena como hexadecimal debido al "0x" inicial. La notación hexadecimal todavía está en su
lugar; solo se ha eliminado el octal.

Si deseas convertir un número binario en un entero, simplemente cambia la base:

parseInt('11', 2); // 3

De manera similar, puedes analizar números de coma flotante utilizando la función incorporada
parseFloat() . A diferencia de su primo parseInt() , parseFloat() siempre usa base 10.

También puedes utilizar el operador + unario para convertir valores en números:

+ '42'; // 42
+ '010'; // 10
+ '0x10'; // 16

Se devuelve un valor especial llamado NaN (abreviatura de "Not a Number" o "No es un número") si la
cadena no es numérica:

parseInt('hello', 10); // NaN

NaN es tóxico: si lo proporcionas como operando para cualquier operación matemática, el resultado
también será NaN :

NaN + 5; // NaN

Puedes probar si un valor es NaN utilizando la función incorporada isNaN() :

isNaN(NaN); // true

JavaScript también tiene los valores especiales Infinity e -Infinity :

1 / 0; // Infinity
-1 / 0; // -Infinity

Puedes probar los valores Infinity , -Infinity y NaN utilizando la función integrada isFinite() :

isFinite(1 / 0); // false


isFinite(-Infinity); // false
isFinite(NaN); // false

Las funciones parseInt() y parseFloat() analizan una cadena hasta que alcancen un caracter que no es válido para el formato de
número especificado, luego devuelve el número analizado hasta ese punto. Sin embargo, el operador "+" simplemente convierte la cadena a
NaN si contiene un caracter no válido. Intenta analizar la cadena "10.2abc" con cada método tú mismo en la consola y comprenderás mejor
las diferencias.

Strings)
Las cadenas en JavaScript son secuencias de caracteres Unicode (en-US). Esta debería ser una buena
noticia para cualquiera que haya tenido que lidiar con la internacionalización. Exactamente, son
secuencias de unidades de código UTF-16; cada unidad de código está representada por un número de 16
bits. Cada caracter Unicode está representado por 1 o 2 unidades de código.

Si deseas representar un solo caracter, simplemente usa una cadena que consta de ese único caracter.

Para encontrar la longitud de una cadena (en unidades de código), accede a su propiedad lenght :

'hello'.length; // 5

¡Aquí está nuestra primer pincelada con objetos JavaScript! ¿Mencionamos que también puedes usar
cadenas como objectos? También tienen métodos que te permiten manipular la cadena y acceder a
información sobre la cadena:

'hello'.charAt(0); // "h"
'hello, world'.replace('world', 'mars'); // "hello, mars"
'hello'.toUpperCase(); // "HELLO"

Otros tipos
JavaScript distingue entre null , que es un valor que indica un no valor deliberado (y solo se puede
acceder a él mediante la palabra clave null ), y undefined , que es un valor de tipo undefined que
indica una variable no iniciada es decir, que aún no se le ha asignado un valor. Hablaremos de variables
más adelante, pero en JavaScript es posible declarar una variable sin asignarle un valor. Si hace esto, el
tipo de la variable es undefined . undefined en realidad es una constante.

JavaScript tiene un tipo booleano, con valores posibles true y false (ambos son palabras clave).
Cualquier valor se puede convertir a booleano de acuerdo con las siguientes reglas:

1. false , 0 , cadenas vacías ( "" ), NaN , null , y undefined todos se vuelven false.
2. Todos los demás valores se vuelven true.

Puedes realizar esta conversión explícitamente utilizando la función Boolean() :

Boolean(''); // false
Boolean(234); // true

Sin embargo, esto rara vez es necesario, ya que JavaScript realizará silenciosamente esta conversión
cuando espera un booleano, como en una declaración if (ve más adelante). Por esta razón, a veces
hablamos simplemente de "valores verdaderos" y "valores falsos", es decir, valores que se convierten en
true y false , respectivamente, cuando se convierten en booleanos. Alternativamente, estos valores se
pueden llamar "veracidad" y "falsedad", respectivamente.

Operaciones booleanas como && (and lógico), || (or lógico) y ! (not lógico) son compatibles; ve más
adelante.

Variables
Las nuevas variables en JavaScript se declaran utilizando una de tres palabras clave: let , const o var .

let te permite declarar variables a nivel de bloque. La variable declarada está disponible en el bloque en
el que está incluida.

let a;
let name = 'Simon';

El siguiente es un ejemplo de alcance con una variable declarada con let :

// myLetVariable *no* es visible aquí

for (let myLetVariable = 0; myLetVariable < 5; myLetVariable++) {


// myLetVariable solo es visible aquí
}

// myLetVariable *no* es visible aquí

const te permite declarar variables cuyos valores pretendes nunca cambiar. La variable está disponible
en el bloque en el que se declara.

const Pi = 3.14; // establece la variable Pi


Pi = 1; // arrojará un error porque no puede cambiar una variable constante.

var es la palabra clave declarativa más común. No tiene las restricciones que tienen las otras dos
palabras clave. Esto se debe a que tradicionalmente era la única forma de declarar una variable en
JavaScript. Una variable declarada con la palabra clave var está disponible en la función en la que se
declara.

var a;
var name = 'Simon';

Un ejemplo de ámbito con una variable declarada con var :

// myVarVariable *es* visible aquí

for (var myVarVariable = 0; myVarVariable < 5; myVarVariable++) {


// myVarVariable es visible para toda la función
}

// myVarVariable *es* visible aquí

Si declaras una variable sin asignarle ningún valor, su tipo es undefined .

Una diferencia importante entre JavaScript y otros lenguajes como Java es que en JavaScript, los bloques
no tienen alcance; solo las funciones tienen alcance. Entonces, si una variable se define usando var en
una declaración compuesta (por ejemplo, dentro de una estructura de control if ), será visible para toda la
función. Sin embargo, a partir de ECMAScript 2015, las declaraciones let y const te permiten crear
variables con alcance de bloque.

Operadores
Los operadores numéricos de JavaScript son + , - , * , / y % que es el operador de residuo o resto (que
es lo mismo que módulo (en-US)). Los valores se asignan usando = , y también hay declaraciones de
asignación compuestas como += y -= . Estas se extienden hasta x = x operador y .

x += 5;
x = x + 5;

Puedes usar ++ y -- para incrementar y disminuir respectivamente. Estos se pueden utilizar como
operadores prefijos o sufijos.

El operador + (en-US) también hace concatenación de cadenas:

'hello' + ' world'; // "hello world"

Si agregas una cadena a un número (u otro valor), todo se convierte primero en cadena. Esto podría
hacerte tropezar:

'3' + 4 + 5; // "345"
3 + 4 + '5'; // "75"

Agregar una cadena vacía a algo es una forma útil de convertirla en cadena.

Se pueden realizar comparaciones (en-US) en JavaScript utilizando < , > , <= y >= . Estas funcionan tanto
para cadenas como para números. La igualdad es un poco menos sencilla. El operador doble-igual realiza
la coerción de tipos si le das diferentes tipos, con resultados a veces interesantes:

123 == '123'; // true


1 == true; // true

Para evitar la coerción de tipos, usa el operador triple-igual:

123 === '123'; // false


1 === true; // false

También hay operadores != y !== .

JavaScript también tiene operaciones bit a bit (en-US). Si quieres usarlas, ahí están.

Estructuras de control
JavaScript tiene un conjunto de estructuras de control similar a otros lenguajes de la familia C. Las
declaraciones condicionales son compatibles con if y else ; las puedes encadenarlas si lo deseas:

var name = 'kittens';


if (name == 'puppies') {
name += ' woof';
} else if (name == 'kittens') {
name += ' meow';
} else {
name += '!';
}
name == 'kittens meow';

JavaScript tiene bucles while y bucles do-while . El primero es bueno para bucles básicos; el segundo
bucle para donde deseas asegurarte de que el cuerpo del bucle se ejecute por lo menos una vez:

while (true) {
// ¡un bucle infinito!
}

var input;
do {
input = get_input();
} while (inputIsNotValid(input));

El bucle for de JavaScript es igual que el de C y Java: te permite proporcione la información de control
para tu bucle en una sola línea.

for (var i = 0; i < 5; i++) {


// Se ejecutará 5 veces
}

JavaScript también contiene otros dos bucles for destacados: for ... of

for (let value of array) {


// haz algo con valor
}

y for ... in :

for (let property in object) {


// hacer algo con la propiedad del objeto
}

Los operadores && y || utilizan lógica de cortocircuito, lo cual significa que si ejecutarán su segundo
operando depende del primero. Esto es útil para verificar objetos nulos antes de acceder a sus atributos:

var name = o && o.getName();

O para almacenar en caché los valores (cuando los valores falsos no son válidos):

var name = cachedName || (cachedName = getName());

JavaScript tiene un operador ternario para expresiones condicionales:

var allowed = (age > 18) ? 'yes' : 'no';

La instrucción switch se puede usar para múltiples ramas según un número o cadena:

switch (action) {
case 'draw':
drawIt();
break;
case 'eat':
eatIt();
break;
default:
doNothing();
}

Si no agregas una instrucción break , la ejecución "caerá" al siguiente nivel. Esto muy rara vez es lo que
deseas; de hecho, vale la pena etiquetar específicamente la caída deliberada con un comentario si
realmente lo pretendías para ayudar a la depuración:

switch (a) {
case 1: // caída deliberada
case 2:
eatIt();
break;
default:
doNothing();
}

La cláusula default es opcional. Puedes tener expresiones tanto en la parte del switch como en los
casos si lo deseas; las comparaciones tienen lugar entre los dos utilizando el operador === :

switch (1 + 3) {
case 2 + 2:
yay();
break;
default:
neverhappens();
}

Objetos
Los objetos de JavaScript se pueden considerar como simples colecciones de pares nombre-valor. Como
tal, son similares a:

Diccionarios en Python.

Hashes en Perl y Ruby.


Tablas hash en C y C++.

HashMaps en Java.

Arreglos asociativas en PHP.

El hecho de que esta estructura de datos se utilice tan ampliamente es un testimonio de su versatilidad.
Dado que todo (el núcleo, tipos bar) en JavaScript es un objeto, cualquier programa de JavaScript implica
naturalmente una gran cantidad de búsquedas en tablas hash. ¡Qué bueno que sean tan rápidas!

La parte "name" es una cadena JavaScript, mientras que el valor puede ser cualquier valor de JavaScript,
incluidos más objetos. Esto te permite construir estructuras de datos de complejidad arbitraria.

Hay dos formas básicas de crear un objeto vacío:

var obj = new Object();

Y:

var obj = {};

Estas son semánticamente equivalentes; la segunda se llama sintaxis literal de objeto y es más
conveniente. Esta sintaxis también es el núcleo del formato JSON y se debe preferir en todo momento.

La sintaxis de objeto literal se puede utilizar para iniciar un objeto en su totalidad:

var obj = {
name: 'Carrot',
for: 'Max', // 'for' es una palabra reservada, use '_for' en su lugar.
details: {
color: 'orange',
size: 12
}
};

El acceso a los atributos se puede encadenar:

obj.details.color; // orange
obj['details']['size']; // 12

El siguiente ejemplo crea un prototipo de objeto ( Person ) y una instancia de ese prototipo ( you ).

function Person(name, age) {


this.name = name;
this.age = age;
}

// Define un objeto
var you = new Person('You', 24);
// Estamos creando una nueva persona llamada "You" de 24 años.

Una vez creado, se puede volver a acceder a las propiedades de un objeto de dos formas:

// notación de puntos
obj.name = 'Simon';
var name = obj.name;

Y...

// notación de corchetes
obj['name'] = 'Simon';
var name = obj['name'];
// puedes usar una variable para definir una clave
var user = prompt('¿cuál es su clave?')
obj[user] = prompt('¿cuál es su valor?')

Estas también son semánticamente equivalentes. El segundo método tiene la ventaja de que el nombre de
la propiedad se proporciona como una cadena, lo cual significa que se puede calcular en tiempo de
ejecución. Sin embargo, el uso de este método evita que se apliquen algunas optimizaciones de
minificación y del motor de JavaScript. También se puede utilizar para establecer y obtener propiedades
con nombres palabras reservadas:

obj.for = 'Simon'; // Error de sintaxis, porque 'for' es una palabra reservada


obj['for'] = 'Simon'; // trabaja bien

A partir de ECMAScript 5, las palabras reservadas se pueden utilizar como nombres de propiedad de
objeto "en bruto". Esto significa que no necesitan "vestirse" entre comillas al definir objeto literales.
Consulta la especificación de ES5.

Para obtener más información sobre objetos y prototipos, consulta Object.prototype . Para obtener una
explicación de los prototipos de objetos y las cadenas de prototipos de objetos, consulta Herencia y la
cadena de prototipos.

A partir de ECMAScript 2015, las claves de objeto se pueden definir mediante la variable en notación de
corchetes al crearlas. {[phoneType]: 12345} es posible en lugar de solo
var userPhone = {}; userPhone[phoneType] = 12345 .

Arreglos
Los arreglos en JavaScript en son realidad un tipo especial de objeto. Funcionan de manera muy parecida
a los objetos normales (las propiedades numéricas se pueden acceder naturalmente solo usando la
sintaxis [] ) pero tienen una propiedad mágica llamada ' length '. Este siempre es uno más que el índice
más alto de el arreglo.

Una forma de crear arreglos es la siguiente:

var a = new Array();


a[0] = 'dog';
a[1] = 'cat';

a[2] = 'hen';
a.length; // 3

Una notación más conveniente es usar un arreglo literal:

var a = ['dog', 'cat', 'hen'];


a.length; // 3

Ten en cuenta que array.length no necesariamente es el número de elementos del arreglo. Considera
lo siguiente:

var a = ['dog', 'cat', 'hen'];


a[100] = 'fox';
a.length; // 101

Recuerda — la longitud de el arreglo es uno más que el índice más alto.

Si consultas un índice de arreglo que no existe, obtendrás un valor de undefined :

typeof a[90]; // undefined

Si tienes en cuenta lo anterior sobre [] y length , puedes iterar sobre un arreglo utilizando el siguiente
bucle for :

for (var i = 0; i < a.length; i++) {


// Haz algo con a[i]
}

ES2015 introdujo el bucle más conciso for ... of para objetos iterables como arreglos:

for (const currentValue of a) {


// Haz algo con currentValue
}

También puedes iterar sobre un arreglo utilizando el bucle for ... in , sin embargo, este no itera sobre los
elementos del arreglo, sino los índices del arreglo. Además, si alguien agrega nuevas propiedades a
Array.prototype , también serán iteradas por dicho bucle. Por lo tanto, este tipo de bucle no se
recomienda para arreglos.

Otra forma de iterar sobre un arreglo que se agregó con ECMAScript 5 es arr.forEach() :

['dog', 'cat', 'hen'].forEach(function(currentValue, index, array) {


// Hacer algo con currentValue o array[index]
});

Si deseas agregar un elemento a un arreglo, simplemente hazlo así:

a.push(item);

Los arreglos vienen con varios métodos. Consulta también la


documentación completa para métodos de arreglo .

Nombre del método Descripción

a.toString() Devuelve una cadena con el toString() de cada elemento separado por comas.

a.toLocaleString() Devuelve una cadena con el toLocaleString() de cada elemento separado por comas.

a.concat(item1[, item2[, ...[, itemN]]]) Devuelve un nuevo arreglo con los elementos agregados.

a.join(sep) Convierte el arreglo en una cadena, con valores delimitados por el parámetro sep

a.pop() Elimina y devuelve el último elemento.

a.push(item1, ..., itemN) Agrega elementos al final del arreglo.


Nombre del método Descripción
a.shift() Elimina y devuelve el primer elemento.

a.unshift(item1[, item2[, ...[, itemN]]]) Añade elementos al inicio del arreglo.

a.slice(start[, end]) Devuelve un subarreglo.

a.sort([cmpfn]) Toma una función de comparación opcional.

Te permite modificar un arreglo eliminando una sección y reemplazándola con más


a.splice(start, delcount[, item1[, ...[, itemN]]])
elementos.

a.reverse() Invierte el arreglo.

Funciones
Junto con los objetos, las funciones son el componente principal para comprender JavaScript. La función
más básica no podría ser mucho más sencilla:

function add(x, y) {
var total = x + y;
return total;
}

Esto demuestra una función básica. Una función de JavaScript puede tomar 0 o más parámetros con
nombre. El cuerpo de la función puede contener tantas declaraciones como desees y puedes declarar tus
propias variables que son locales para esa función. La declaración return se puede usar para devolver
un valor en cualquier momento, terminando la función. Si no se utiliza una declaración return (o return
vacía sin valor), JavaScript devuelve undefined .

Los parámetros nombrados resultan ser más intuitivos que cualquier otra cosa. Puedes llamar a una
función sin pasar los parámetros que espera, en cuyo caso se establecerán en undefined .

add(); // NaN
// No puedes realizar sumas en undefined

También puedes pasar más argumentos de los que espera la función:

add(2, 3, 4); // 5
// sumó los dos primeros; el 4 fue ignorado

Eso puede parecer un poco tonto, pero las funciones tienen acceso a una variable adicional dentro de su
cuerpo llamada argumentos , que es un objeto tipo arreglo que contiene todos los valores pasados a la
función. Reescribamos la función de suma para tomar tantos valores como queramos:

function add() {
var sum = 0;
for (var i = 0, j = arguments.length; i < j; i++) {
sum += arguments[i];
}
return sum;
}

add(2, 3, 4, 5); // 14

Sin embargo, eso no es más útil que escribir 2 + 3 + 4 + 5 . Creemos una función de promedio:

function avg() {
var sum = 0;
for (var i = 0, j = arguments.length; i < j; i++) {
sum += arguments[i];
}
return sum / arguments.length;
}
avg(2, 3, 4, 5); // 3.5

Esta es bastante útil, pero parece un poco detallada. Para reducir un poco más este código, podemos
considerar la sustitución del uso del arreglo de argumentos a través de la sintaxis del parámetro Rest . De
esta manera, podemos pasar cualquier número de argumentos a la función manteniendo nuestro código
mínimo. El operador de parámetro rest se usa en listas de parámetros de función con el formato:
...variable e incluirá dentro de esa variable la lista completa de argumentos no capturados a los que se
llamó la función. with . También reemplazaremos el bucle for con un bucle for...of para devolver los
valores dentro de nuestra variable.

function avg(...args) {
var sum = 0;
for (let value of args) {
sum += value;
}
return sum / args.length;
}

avg(2, 3, 4, 5); // 3.5

En el código anterior, la variable args contiene todos los valores que se pasaron a la función.

Es importante tener en cuenta que dondequiera que se coloque el operador de parámetro rest en una declaración de función, almacenará
todos los argumentos después de su declaración, pero no antes. es decir, function avg(firstValue, ...args) almacenará el primer valor pasado
a la función en la variable firstValue y los argumentos restantes en args. Esa es otra característica útil del lenguaje, pero nos lleva a un
nuevo problema. La función avg() toma una lista de argumentos separados por comas, pero ¿qué sucede si deseas encontrar el promedio
de un arreglo? Simplemente, podrías reescribir la función de la siguiente manera:

function avgArray(arr) {
var sum = 0;
for (var i = 0, j = arr.length; i < j; i++) {
sum += arr[i];
}
return sum / arr.length;
}

avgArray([2, 3, 4, 5]); // 3.5

Pero sería bueno poder reutilizar la función que ya hemos creado. Afortunadamente, JavaScript te permite
llamar a una función con un arreglo arbitrario de argumentos, usando el método apply() de cualquier
objeto función.

avg.apply(null, [2, 3, 4, 5]); // 3.5

El segundo argumento de apply() es el arreglo que se utilizará como arguments ; el primero se


explicará más adelante. Esto enfatiza el hecho de que las funciones también son objetos.

Puedes lograr el mismo resultado utilizando el operador de propagación (en-US) en la llamada de función.

Por ejemplo: avg(...numbers)

JavaScript te permite crear funciones anónimas.

var avg = function() {


var sum = 0;
for (var i = 0, j = arguments.length; i < j; i++) {
sum += arguments[i];
}
return sum / arguments.length;
};

Esto semánticamente es equivalente a la forma function avg() . Es extremadamente poderosa, ya que


te permite colocar una definición de función completa en cualquier lugar donde normalmente colocarías

una expresión. Esto permite todo tipo de ingeniosos trucos. Aquí hay una forma de "ocultar" algunas
variables locales — como alcance de bloque en C:

var a = 1;
var b = 2;

(function() {
var b = 3;
a += b;
})();

a; // 4
b; // 2

JavaScript te permite llamar a funciones de forma recursiva. Esto es particularmente útil para tratar con
estructuras de árbol, como las que se encuentran en el DOM del navegador.

function countChars(elm) {
if (elm.nodeType == 3) { // TEXT_NODE
return elm.nodeValue.length;
}
var count = 0;
for (var i = 0, child; child = elm.childNodes[i]; i++) {
count += countChars(child);
}
return count;
}

Esto resalta un problema potencial con las funciones anónimas: ¿cómo las llama de forma recursiva si no
tienen un nombre? JavaScript te permite nombrar expresiones de función para esto. Puedes utilizar IIFE
(expresiones de función invocadas inmediatamente) con nombre como se muestra a continuación:

var charsInBody = (function counter(elm) {


if (elm.nodeType == 3) { // TEXT_NODE
return elm.nodeValue.length;
}
var count = 0;
for (var i = 0, child; child = elm.childNodes[i]; i++) {
count += counter(child);
}
return count;
})(document.body);

El nombre proporcionado a una expresión de función como arriba solo está disponible para el alcance de
la función. Esto permite que el motor realice más optimizaciones y da como resultado un código más
legible. El nombre también aparece en el depurador y en algunos seguimientos de la pila, lo cual puede
ahorrarte tiempo al depurar.

Ten en cuenta que las funciones de JavaScript en sí mismas son objetos, como todo lo demás en
JavaScript, y puedes agregar o cambiar propiedades en ellas tal como hemos visto anteriormente en la
sección Objetos.

Objetos personalizados

Para obtener una descripción más detallada de la programación orientada a objetos en JavaScript, consulta Introducción a JavaScript
orientado a objetos (en-US).

En la programación clásica orientada a objetos, los objetos son colecciones de datos y métodos que
operan sobre esos datos. JavaScript es un lenguaje basado en prototipos que no contiene una declaración
de clase, como la encontrarías en C++ o Java (esto, a veces es confuso para los programadores
acostumbrados a lenguajes con una declaración de clase). En cambio, JavaScript usa funciones como
clases. Consideremos un objeto person con campos first y last name . Hay dos formas de mostrar el
nombre: como "primero último" o como "último, primero". Usando las funciones y objetos que hemos
explicado anteriormente, podríamos mostrar los datos de esta manera:

function makePerson(first, last) {


return {
first: first,
last: last
};
}
function personFullName(person) {
return person.first + ' ' + person.last;
}
function personFullNameReversed(person) {
return person.last + ', ' + person.first;
}

var s = makePerson('Simon', 'Willison');


personFullName(s); // "Simon Willison"
personFullNameReversed(s); // "Willison, Simon"

Esto funciona, pero es bastante feo. Terminas con docenas de funciones en tu espacio de nombres global.
Lo que realmente necesitamos es una forma de enlazar una función a un objeto. Dado que las funciones
son objetos, esto es fácil:

function makePerson(first, last) {


return {
first: first,
last: last,
fullName: function() {
return this.first + ' ' + this.last;
},
fullNameReversed: function() {
return this.last + ', ' + this.first;
}
};
}

var s = makePerson('Simon', 'Willison');


s.fullName(); // "Simon Willison"
s.fullNameReversed(); // "Willison, Simon"

Nota sobre la palabra clave this . Usada dentro de una función, this se refiere al objeto actual. Lo que
realmente significa está especificado por la forma en que llamaste a esa función. Si lo llamaste usando
notación de puntos o notación de corchetes (en-US) en un objeto, ese objeto se convierte en this . Si la
notación de puntos no se usó para la llamada, this se refiere al objeto global.

Ten en cuenta que this es una frecuente causa de errores. Por ejemplo:

var s = makePerson('Simon', 'Willison');


var fullName = s.fullName;
fullName(); // undefined undefined

Cuando llamamos a fullName() solo, sin usar s.fullName() , this está vinculado al objeto global.
Debido a que no hay variables globales llamadas first o last obtenemos undefined para cada una.

Podemos aprovechar la palabra clave this para mejorar nuestra función makePerson :

function Person(first, last) {


this.first = first;
this.last = last;
this.fullName = function() {
return this.first + ' ' + this.last;
};
this.fullNameReversed = function() {
return this.last + ', ' + this.first;
};
}
var s = new Person('Simon', 'Willison');

Hemos introducido otra palabra clave: new . new está fuertemente relacionado con this . Crea un nuevo
objeto vacío y luego llama a la función especificada, con this configurado para ese nuevo objeto. Sin

embargo, ten en cuenta que la función especificada con this no devuelve un valor, sino que simplemente
modifica el objeto this . Es new que devuelve el objeto this al sitio que realiza la llamada. Las
funciones que están diseñadas para ser llamadas por new se denominan funciones constructoras. La
práctica común es poner en mayúscula estas funciones como recordatorio para llamarlas con new .

La función mejorada todavía tiene el mismo error al llamar a fullName() sola.

Nuestros objetos person están mejorando, pero todavía tienen algunos bordes desagradables. Cada vez
que creamos un objeto person , estamos creando dos nuevos objetos de función dentro de él, ¿no sería
mejor si este código fuera compartido?

function personFullName() {
return this.first + ' ' + this.last;
}
function personFullNameReversed() {
return this.last + ', ' + this.first;
}
function Person(first, last) {
this.first = first;
this.last = last;
this.fullName = personFullName;
this.fullNameReversed = personFullNameReversed;
}

Eso es mejor: estamos creando las funciones como métodos solo una vez y asignándoles referencias
dentro del constructor. ¿Podemos hacer algo mejor que eso? La respuesta es sí:

function Person(first, last) {


this.first = first;
this.last = last;
}
Person.prototype.fullName = function() {
return this.first + ' ' + this.last;
};
Person.prototype.fullNameReversed = function() {
return this.last + ', ' + this.first;
};

Person.prototype es un objeto compartido por todas las instancias de Person . Forma parte de una
cadena de búsqueda (que tiene un nombre especial, "cadena de prototipos"): cada vez que intentes
acceder a una propiedad de Person que no esté configurada, JavaScript revisará Person.prototype
para ver si esa propiedad existe allí. Como resultado, todo lo asignado a Person.prototype pasa a estar
disponible para todas las instancias de ese constructor a través del objeto this .

Esta es una herramienta increíblemente poderosa. JavaScript te permite modificar el prototipo de algo en
cualquier momento en tu programa, lo cual significa que —en tiempo de ejecución— puedes agregar
métodos adicionales a los objetos existentes:

var s = new Person('Simon', 'Willison');


s.firstNameCaps(); // TypeError en la línea 1: s.firstNameCaps no es una función

Person.prototype.firstNameCaps = function() {
return this.first.toUpperCase();
};
s.firstNameCaps(); // "SIMON"

Curiosamente, también puedes agregar cosas al prototipo de objetos JavaScript integrados. Agreguemos
un método a String que devuelva esa cadena a la inversa:

var s = 'Simon';
s.reversed(); // TypeError en la línea 1: s.reversed no es una función

String.prototype.reversed = function() {
var r = '';
for (var i = this.length - 1; i >= 0; i--) {
r += this[i];
}

return r;
};

s.reversed(); // nomiS

¡Nuestro método new funciona incluso con cadenas literales!

'Esto ahora se puede revertir'.reversed(); // ritrever edeup es aroha otsE

Como se mencionó anteriormente, el prototipo forma parte de una cadena. La raíz de esa cadena es Object.prototype , cuyos

var s = new Person('Simon', 'Willison');


s.toString(); // [object Object]

Person.prototype.toString = function() {
return '<Person: ' + this.fullName() + '>';
}

s.toString(); // "<Person: Simon Willison>"

¿Recuerda cómo avg.apply() tenía un primer argumento null ? Ahora lo podemos revisar. El primer argumento de apply() es

function trivialNew(constructor, ...args) {


var o = {}; // Crea un objeto
constructor.apply(o, args);
return o;
}

Esta no es una réplica exacta de new ya que no configura la cadena de prototipos (sería difícil de ilustrar). Esto no es

Llamar a...

var bill = trivialNew(Person, 'William', 'Orange');

...por tanto, casi es equivalente a

var bill = new Person('William', 'Orange');

apply() tiene una función hermana llamada call() , que nuevamente te permite establecer this pero toma una lista de arg

function lastNameCaps() {
return this.last.toUpperCase();
}
var s = new Person('Simon', 'Willison');
lastNameCaps.call(s);
// Es lo mismo que:
s.lastNameCaps = lastNameCaps;
s.lastNameCaps(); // WILLISON

Funciones internas
Las declaraciones de función de JavaScript están permitidas dentro de otras funciones. Hemos visto esto una vez antes, c

function parentFunc() {
var a = 1;

function nestedFunc() {
var b = 4; // parentFunc no puede usar esto
return a + b;
}
return nestedFunc(); // 5
}

Esto proporciona una gran utilidad para escribir un código más fácil de mantener. Si una función llamada se basa en una

Esto también contrarresta el atractivo de las variables globales. Al escribir código complejo, a menudo es tentador util

Cierres
Esto nos lleva a una de las abstracciones más poderosas que JavaScript tiene para ofrecer — pero potencialmente, también

function makeAdder(a) {
return function(b) {
return a + b;
};
}
var add5 = makeAdder(5);
var add20 = makeAdder(20);
add5(6); // ?
add20(7); // ?

El nombre de la función makeAdder() lo debería revelar: crea nuevas funciones ' adder ', cada una de las cuales, cuando s

Lo que está sucediendo aquí es más o menos lo mismo que sucedía anteriormente con las funciones internas: una función def

add5(6); // returns 11
add20(7); // devuelve 27

Esto es lo que está sucediendo realmente. Siempre que JavaScript ejecuta una función, se crea un objeto ' scope ' para con

Entonces, cuando se llama a makeAdder() , se crea un objeto scope con una propiedad: a , que es el argumento que se pasa

Los objetos scope forman una cadena llamada cadena de ámbito, similar a la cadena de prototipos utilizada por el sistema

Un cierre es la combinación de una función y el objeto scope en el que se creó. Los cierres te permiten guardar el estad

Last modified: 17 nov 2021, by MDN contributors

También podría gustarte