Javascript

@alfonsomartinde

Introducción a

Under construction

JavaScript es un bloque de mármol, y hay que desechar las virutas hasta que la verdadera naturaleza del lenguaje se revele.

Douglas Crockford, "JavaScript: The Good Parts" (2008)

"

Introducción

El 99% de las páginas web usa javascript.

 

Todos los navegadores modernos (desktop, consolas, smartphones, smart TV, e incluso plataformas electrónicas como Arduino o Raspberry Pi) incluyen intérpretes Javascript.

 

Todo esto convierte a Javascript en el lenguaje más omnipresente de la historia.

Historia

Principios básicos

Tipos de datos

Arrays

Objetos

Declaraciones vs expresiones

Funciones

Closures

Herencia prototípica

DRY, KISS, YAGNI, Patrones

H

Historia

Creado originalmente por Brendan Eich, en Netscape (ahora Mozilla).

"Mocha"

"LiveScript"

"JavaScript"

Evolución de sus nombres:

Los navegadores antiguamente se limitaban a representar el código HTML. Hacía falta incorporar funcionalidad, y Netscape se puso manos a la obra.

"JavaScript": marca registrada por Sun (ahora Oracle), usada para describir la interpretación del estándar hecha por Mozilla.

Mozilla envió su Javascript a la Asociación Europea de Fabricantes de Computadoras (ECMA), para que lo estandarizaran.

La versión estandarizada se llama "ECMAscript".

¿JavaScript? ¿ECMAscript?

Historia

Java (sintaxis, valores primitivos vs objetos)

Scheme y AWK (funciones de primera clase)

Self (herencia prototípica)

Perl y Python (cadenas, arrays y expresiones regulares)

Influencias de otros lenguajes

Historia

No tuvo captura de excepciones hasta ECMAScript3, lo cual explica por qué el lenguaje realiza coherción de datos automática, y produce errores silenciosos.

Durante la última década, todos los navegadores han implementado la versión 3 de ECMAscript.

En 2011, se aprobó la versión 5 de ECMAscript, también llamada "ECMA-262 5th edition".

ECMAscript

Historia

¿Qué trajo nuevo ES5?

Historia

Modo estricto: "use strict";

Más controles para verificar que no se haya cometido algún error en nuestro código.

Se reducen funcionalidades del lenguaje que puedan incitar a errores.

Precauciones:

Cuidado al concatenar y/o minificar, que no se pierda el "use scrict"

Cuidado al contar con funcionalidades de modo estricto, en navegadores que no las soportan.

¿Qué trajo nuevo ES5?

Historia

Modo estricto: "use strict";

Todas las variables deben declararse con var. Evitamos ensuciar scope global.

Las funciones al principio del scope. No se permite repetir parámetros.

Se simplifica 'arguments': arguments.callee y arguments.caller se eliminan. Los valores de arguments no cambian aunque cambiemos los parámetros.

Se elimina sintaxis en octal. Sin modo estricto: 010 === 8  // true

Dentro de las funciones que no son métodos, this === undefined. Bueno para constructores: si se usa un constructor como si fuese función, da error.

Se elimina with

¿Qué trajo nuevo ES5?

Historia

Nuevos métodos para Array y Date

Array.isArray()

Array.prototype.filter()
Array.prototype.forEach()
Array.prototype.indexOf()
Array.prototype.lastIndexOf()
Array.prototype.map()
Array.prototype.reduce()
Array.prototype.some()
Array.prototype.every()
Date.now()
Date.prototype.toISOString()

¿Qué trajo nuevo ES5?

Historia

Soporte para JSON, y nuevos métodos .toJSON()

JSON.parse()
JSON.stringify()
Boolean.prototype.toJSON()
Number.prototype.toJSON()
String.prototype.toJSON()
Date.prototype.toJSON()

¿Qué trajo nuevo ES5?

Historia

Atributos

Las propiedades ya no son sólo "nombre":valor, ahora son "nombre" y 4 atributos: su valor, si se puede editar, si debe permanecer oculta, o si se pueden reconfigurar sus atributos.

{
  value: ...,
  writable: false,
  enumerable: false,
  configurable: false
}

Data atributes:

property descriptor

¿Qué trajo nuevo ES5?

Historia

Atributos por defecto

writable: false,
enumerable: false,
configurable: false
var o = {};

Object.defineProperty(o, "x", { 
  value : 1, 
  writable: true,
  enumerable: false,
  configurable: true
});

¿Qué trajo nuevo ES5?

Historia

Object.keys(o) // enumerable === false

// [ ]

Atributos: enumerable

El atributo enumerable, sirve par definir si la propiedad se puede enumerar en un for, o con Object.keys():

¿Qué trajo nuevo ES5?

Historia

var persona = {};
Object.defineProperty(persona, 'edad', {
    value: 42
});

Si definimos un objeto con defineProperty, y no especificamos nada, por defecto writtable: false. Es una forma de definir objetos de solo lectura.

Atributos: writable

persona.edad = 21;
console.log( persona.edad );

// 42.

¿Qué trajo nuevo ES5?

Historia

El atributo configurable, controla que la propiedad bo se pueda modificar ni borrar. Si configurable: false, sólo podemos cambiar writtable a false, nunca a true.

Atributos: configurable

var o = {};
Object.defineProperty(o, 'a', {
  get: function() { return 1; },
  configurable: false
});

Object.defineProperty(o, 'a', { configurable: true }); // TypeError
Object.defineProperty(o, 'a', { enumerable: true });   // TypeError
Object.defineProperty(o, 'a', { set: function() {} }); // TypeError
Object.defineProperty(o, 'a', { get: function() { return 1; } }); // TypeError
Object.defineProperty(o, 'a', { value: 12 });          // TypeError

delete o.a;       // No se borra!
console.log(o.a); // 1

¿Qué trajo nuevo ES5?

Historia

Object.defineProperty(o, "x", { value: 2 });
o.x // 2. Ha cambiado su valor

Si configurable es true, entonces podemos hacer lo que queramos:

Atributos: configurable

var o = {};

Object.defineProperty(o, "x", { 
  value : 1, 
  writable: true,
  enumerable: false,
  configurable: true
});

¿Qué trajo nuevo ES5?

Historia

Accesores: getters & setters

Los accesores son propiedades que a su vez permiten acceder o definir el valor de otra propiedad del mismo objeto. No tienen atributo value ni writable.

{
  get function...,
  set function,
  enumerable: true,
  configurable: true
}

Accessor atributes:

property descriptor

O usamos accesores, o usamos value, no ambos.

¿Qué trajo nuevo ES5?

Historia

// Cambiamos "x" de data property, a accessor property
Object.defineProperty(o, "x", {
    get: function() {
        return 0;
    }
});
o.x // => 0

Podemos especificar getters y setters para cualquier propiedad del objeto, en vez de especificar el value.

Accesores: getters & setters: forma estándar

var p = Object.defineProperties({}, {
    x: { value: 1, writable: true, enumerable:true, configurable:true }, 
    y: { value: 1, writable: true, enumerable:true, configurable:true },
    r: { 
        get: function() { return Math.sqrt(this.x*this.x + this.y*this.y) },
        enumerable: true,
        configurable:true
    }
});

¿Qué trajo nuevo ES5?

Historia

Con Object.defineProperties(), podemos definir todas las propiedades y sus respectivos atributos, de una vez. El primer argumento, es el objeto que se va a definir.

Accesores: getters & setters: forma estándar

var persona = {
    nombre: 'Pepe',
    apellido: 'López',
    get nombreCompleto() {  // Sin los :
        return this.nombre + ' ' + this.apellido;
    },
    set nombreCompleto( str ) {  // Sin los :
        var arrNombre = str.toString().split(' ');
        this.nombre   = arrNombre[ 0 ] || '';
        this.apellido = arrNombre[ 1 ] || '';
    }
}

persona.nombreCompleto = 'Ana Sánchez';
console.log( persona.nombre );    // Ana 
console.log( persona.apellido );  // Sánchez

¿Qué trajo nuevo ES5?

Historia

Accesores: getters & setters: forma abreviada

¿Qué trajo nuevo ES5?

Historia

Bloqueo de objetos

Object.preventExtensions()
Object.isExtensible()
Object.seal()
Object.isSealed()
Object.freeze()
Object.isFrozen()

Impide añadir nuevas propiedades

preventExtensions + configurable:false
(no se pueden añadir,  ni borrar ni reconfigurar)

preventExtensions + configurable:false + writable: false

IE7

IE8

IE9*

IE10

IE11

Ffox

Chr

ES5

ES6

* En IE9 no funciona el modo estricto

Compatibilidad

ECMAscript

ES3

Intérpretes

ECMAscript

Son incluidos en los navegadores, para interpretar el código JavaScript, y ejecutar los scripts. 

 

El primero se lo debemos a Brendan Eich y fue llamado "SpiderMonkey", para NetScape (Mozilla).

 

Los navegadores web generalmente usan una API pública para crear los host objects, a los que tendrá acceso JavaScript: window, document, location, history, XMLHttpRequest, etc.

Mozilla: SpiderMonkey, TraceMonkey

Java: Rhino

Chrome, Node.js y V8.NET: V8

Safari: SquirrelFish, Nitro

Internet Explorer: Chakra, JScript

Opera: Carakan

Flash: Tamarin

Konqueror: KJS

Intérpretes

ECMAscript

Se está trabajando desde hace unos años en la versión 6, también llamada "Harmony", o "ES.next". Está prácticamente terminada.

ECMAscript 6

El futuro...

En junio de 2015, será la publicación oficial.

Historia

Principios básicos

Tipos de datos

Arrays

Objetos

Declaraciones vs expresiones

Funciones

Closures

Herencia prototípica

DRY, KISS, YAGNI, Patrones

P

Principios básicos

Características del lenguaje:

  • Usa la codificación UTF-16 del juego de caracteres Unicode.
  • Case sensitive.
  • Ignora espacios en blanco.
  • Identificadores y palabras reservadas.
  • Semicolon automático.
  • Tipos de datos.
  • Basado en prototipos.
  • Funciones: objetos de primera clase.
  • Alcance léxico (lexical scope). Hoisting.
  • Tipado dinámico y blando (débil). Coerción. Falsy values
  • Multiparadigma.

Unicode

Principios básicos

JavaScript se diseñó en la época en la que se esperaba que Unicode almacenase como mucho 216 caracteres (65.536). Desde entonces ha crecido para dar capacidad a más de 1.000.000 de caracteres.

 

Los caracteres en JavaScript son de 16bits (16bits Unicode). Si queremos representar alguno de los que no caben en esos primeros 65536, debemos usar dos caracteres.

"é" === "\u00E9"  // true. Idénticos a nivel de bit.

"é" === "e\u0301" // false: diferente nº de caracteres.

Unicode

Principios básicos

Javascript entiende dos caracteres Unicode, como dos caracteres diferentes. 

 

Por ejemplo: el acento, se representa con "\u0301", con lo cual la letra é puede representarse en Unicode también como "e\u0301".

  BAD PART!

Unicode

Principios básicos

Existen algunos caracteres UTF-16, que necesitan dos caracteres Unicode: "surrogate pair":

  BAD PART!

var pi = "π"    // π usa 1 caracter de 16-bit: 0x03c0
var e = "e"     // e usa 1 caracter de 17-bit: 0x1d452

pi.length === 1 // sólo necesita 1 catacter de 16-bit
e.length === 2  // necesita 2 caracteres de 16-bit: "\ud835\udc52"

Identificadores y palabras reservadas

Principios básicos

En JavaScript son válidos los identificadores que comienzan con cualquier letra, "_" o "$". Los números no se permiten como primer caracter.

 

También se permiten letras con acentos, y cualquier símbolo Unicode, sin embargo es recomendable utilizar solo caracteres y dígitos ASCII.

Identificadores y palabras reservadas

Principios básicos

No se pueden usar como identificadores:

break
case
catch
continue
debugger
default
delete
do
else
false
finally
for
function
if
in
instanceof
new
null
return
switch
this
throw
true
try
typeof
var
void
while
with

Identificadores y palabras reservadas

Principios básicos

Si utilizamos ECMAScript5, tampoco podremos usar:

class
const
enum
export
extends
import
super

Con "use strict" no podemos usar:

arguments
eval
implements
interface
let
package
private
protected
public
static
yield

Identificadores y palabras reservadas

Principios básicos

Debemos evitar usar variables o funciones predefinidas. Lo mismo ocurre con los navegadores, y otros clientes con JavaScript embebido: window, DOM

Array
Boolean
Date
decodeURI
decodeURIComponent
encodeURI
encodeURIComponent
Error
EvalError
Function
Infinity
isFinite
isNaN
JSON
Math
NaN
Number
Object
parseFloat
parseInt
RangeError
ReferenceError
RegExp
String
SyntaxError
TypeError
undefined
URIError

Semicolon automático

Principios básicos

Esta es una de las partes malas del lenguaje. En ciertas ocasiones puede producir errores silenciosos.

 

No se aplica break en ++ o --

  BAD PART!

function getObjeto(){
  return
  {
    nombre: "Alberto",
    status: true
  };
}

getObjeto();

// undefined !!

Basado en prototipos

Principios básicos

Javascript en un poco confuso para programadores con experiencia en lenguajes basados en clases, como C++ o Java, ya que es dinámico y no provee una implementación de clases, a pesar de que "class" es una palabra clave del lenguaje, y no puede ser unada como nombre de variables.

 

Refiriéndonos a herencia, JavaScript tiene solo un constructor: objetos. Cada objeto tiene un enlace interno que apunta a otro objeto, al que llamamos "prototipo interno(__proto__)

Basado en prototipos

Principios básicos

Dicho objeto interno, tiene a su vez otro objeto interno que apunta a su padre, y así sucesivamente hasta que se llega a un objeto cuyo prototype interno es null.

a = {}

__proto__

Object

__proto__

null

"a", ha heredado los métodos y propiedades de Object, a través de su prototipo interno.

a.hasOwnProperty()

Basado en prototipos

Principios básicos

A parte de heredar de objetos nativos, podemos crear nuestros propios objetos, con los que crear nuevas instancias del mismo. En este caso, seguiremos usando el prototipo interno, pero además podremos añadirle un prototipo externo, con la propiedad prototype.

 

El __proto__ de la instancia, apunta al prototype del constructor, es decir, hereda sus propiedades y métodos.

Basado en prototipos

Principios básicos

function Alumno(){};
console.dir( Alumno );

En JavaScript, los constructores se crean con funciones. Todas las funciones en JavaScript, tienen una propiedad que se llama "prototype" (prototipo externo), a parte del "__proto__" (prototipo interno)

Basado en prototipos

Principios básicos

Funciones: objetos de primera clase

Principios básicos

Esto significa que JavaScript permite:

  • Pasar funciones como argumento de otras funciones.
  • Usar funciones anónimas y anidadas.
  • Acceder a variables no locales, y crear closures.
  • Retornar funciones como valor de otras funciones.
  • Asignar funciones como valor de una variable.
  • Almacenar funciones dentro de otras estructuras.

Programación funcional

Alcance léxico (scope)

Principios básicos

Las variables declaradas fuera de una función, se convierten en globales, no pueden ser borradas por el recolector de basura, y son visibles en cualquier parte de la aplicación.

Function scope: Las variables declaradas dentro de una función, con la palabra clave "var", tienen un ámbito de función, y sólo están accesibles al código que haya dentro de esa función.

Alcance léxico (scope)

Principios básicos

var scope = "global";
function checkscope() {
    var scope = "local";
    return scope;
}
checkscope();
scope = "global";
function checkscope2() {
    scope = "local";
    myscope = "local";
    return [scope, myscope];
}
checkscope2();
scope;
myscope;

Declarada de forma global

Declarada de forma local

// "local"

// ["local","local"]

// "local"

// "local"

Alcance léxico (scope)

Principios básicos

var scope = "global scope";
function checkscope() {
    var scope = "local scope";
    function nested() {
        var scope = "nested scope";
        return scope;
    }
    return nested();
}
checkscope();

Anidación de alcances

// "nested scope"

Alcance léxico (closures)

Principios básicos

Las funciones son ejecutadas usando el alcance de las variables que estaba en efecto cuando fueron definidas, y no el alcance de variables que estaba en efecto cuando fueron invocadas.

 

Para implementar el alcance léxico, el estado interno de la función tiene que incluir no sólo su código, sino también una referencia al alcance que estaba en efecto al definirse.

Alcance léxico (closures)

Principios básicos

var scope = "global scope";
function checkscope() {
    var scope = "local scope";
    function nested() {
        return scope;
    }
    return nested();
}
checkscope();

Closures

Cuando ejecuto checkscope(), la función nested se vuelve a definir. En ese momento, scope vale "local scope".

 

La función nested la invoco justo cuando fue definida.

// "local scope"

Alcance léxico (closures)

Principios básicos

var scope = "global scope";
function checkscope() {
    var scope = "local scope";
    function nested() {
        return scope;
    }
    return nested;
}
checkscope()();

Closures

Cuando ejecuto checkscope(), la función nested se vuelve a definir. En ese momento, scope vale "local scope".

 

Al ejecutar checkscope(), lo que hago es retornar la funcion nested, y la invoco fuera de donde fue definida. scope, fuera de checkscope, vale "global scope"

// "local scope" !!

Lo que cuenta es cuando fue definida

Hoisting

Principios básicos

hoist: "Elevador"

Los motores de JavaScript "elevan" las declaraciones de funciones al inicio del programa, y las declaraciones de variables al inicio de su alcance.

Hoisting

Principios básicos

var scope = "global";
function f() {
    console.log(scope);
    var scope = "local";
    console.log(scope);
}

// undefined

// "local"

var scope = "global";
function f() {
    var scope;
    console.log(scope);
    scope = "local";
    console.log(scope);
}

El anterior código es traducido a:

Tipado dinámico

Principios básicos

Permite modificar el tipo de variable, en tiempo de ejecución, aunque ya haya sido declarada.

var nombre = "Pepe",
    edad = 24;    // se declara como int

// Resto de código

edad = "24 años"; // ahora es string

Tipado blando: coerción de datos

Principios básicos

Al relegar la conversión de datos al intérprete interno, a menudo se precisa de modificar los valores para adaptarlos y poder realizar operaciones entre ellos.

Suma: se realizan siguiendo un orden estricto de izquierda a derecha. Si se encuentra una cadena, se convierte todo a cadena.

Resto de operaciones: JavaScript siempre trata de convertir en primer lugar las cadenas en números.

Tipado blando: coerción de datos

Principios básicos

console.log(1 + 2 + 3);
console.log(1 + "2" + 3);
console.log(1 + 2 + "3");

// 6

// "123"

// "33"

console.log(1 + "a" + 3);

// "1a3"

console.log("3" - "2");

// 0

console.log("3" - 2 - 1);

// NaN

console.log(3 - 2 - "a");

// 1

Tipado blando: coerción de datos

Principios básicos

Otro lugar donde se produce coerción de datos, es en las comparaciones simples (==).

'' == '0'          // false
0 == ''            // true
0 == '0'           // true
false == 'false'   // false
false == '0'       // true
false == undefined // false
false == null      // false
null == undefined  // true
' \t\r\n ' == 0    // true

Usar siempre comparación estricta (===)

  BAD PART!

Falsy values

Principios básicos

Value        Type
---------    ---------
0            Number
NaN          Number
''           String
false        Boolean
null         Object
undefined    Undefined

Todos ellos son false, si usamos comparación normal (==)

Multiparadigma

Principios básicos

Programación imperativa

Programación funcional

Programación Orientada a Objetos

JavaScript es un lenguaje multiparadigma, es decir, nos permite abordar nuestros desarrollos empleando múltiples paradigmas:

Historia

Principios básicos

Tipos de datos

Arrays

Objetos

Declaraciones vs expresiones

Funciones

Closures

Herencia prototípica

DRY, KISS, YAGNI, Patrones

T

Tipos de datos

Tipos primitivos e inmutables

Tipos objeto y mutables

Números

Cadenas

Booleanos

null

undefined

Todo lo demás

Números

Tipos de datos

Todos los números son reales: 64 bits, coma flotante IEEE754.

 

1 === 1.0  // true

 

Lo único que debemos saber de un número en JavaScript, es que es un número. No existen errores por usar números por encima del máximo o del mínimo.

 

typeof 5 === "number"

Number.MAX_VALUE === 1.7976931348623157e+308.

Number.MIN_VALUE === 5e-308.

 

Infinity: todos aquellos valores por encima del valor máximo.

-Infinity: todos los que están por debajo del mínimo.

 

Si intentamos representar un número cercano a cero, fuera de rango, devuelve 0, o -0.

 

Tampoco devuelve error si dividimos por cero: devuelve Infinity o NaN (0/0)

Números

Tipos de datos

Números

Tipos de datos

1/0 === Infinity
-1/0 === -Infinity

Number.MAX_VALUE + 1 === Infinity
-Number.MIN_VALUE -1 === -Infinity

1/Infinity === 0
1/Infinity === -0
-1/Infinity === 0
-1/Infinity === -0

isFinite( NaN )     // false
isFinite( 1/0 )     // false

isFinite() devuelve true si no es NaN, Infinity o - Infinity.

Números

Tipos de datos

El valor NaN es un valor numérico resultante de una operación que no ha producido un resultado normal. Se puede detectar con isNaN():

isNaN( 0/0 )      // true
isNaN( 1 + "a" ); // true

0 / 0                // NaN
Infinity / Infinity  // NaN
Math.sqrt( -3 )      // NaN

NaN === NaN   // false
x !== x       // Si, y sólo si x es NaN
isNaN( x )    // true

Números

Tipos de datos

El objeto Math, permite realizar múltiples operaciones matemáticas. Algunos ejemplos:

Math.round( 0.3 )    // 1  Devuelve el entero más cercano
Math.ceil( 0.3 )     // 1  Devuelve entero más cercano por arriba
Math.floor( 0.3 )    // 0  Devuelve en entero más cercano por abajo
Math.abs( -3 )       // 3  Devuelve valor absoluto

Math.max( 1, 2, 3 )  // 3  Devuelve el mayor
Math.min( 1, 2, 3 )  // 1  Devuelve el menor

Math.PI              // Número Pi
Math.E               // Número e

Cadenas

Tipos de datos

Una cadena es una secuencia de ordenada e inmutable de valores de 16bits, cada uno de los cuales representa un caracter Unicode.

 

La forma de concatenar cadenas es con el signo +:

 

"g" + "a" + "t" + "o" === "gato"

 

typeof "pepe" === "string"

Cadenas

Tipos de datos

Heredan varios métodos del objeto String (wrapper object).

var s = "Hola, mundo";

s.charAt( 0 )               // "h"  El primer caracter
s.charAt( s.length - 1 )    // "o"  El último caracter
s.substring( 1, 4 )         // "ola"  1er, 2do y 3er caracteres
s.slice( 1, 4 )             // "ola"  1er, 2do y 3er caracteres
s.slice( -3 )               // "ndo"  3 últimos caracteres
s.indexOf( "o" )            // 1  Posición de la primera "o"
s.lastIndexOf( "o" )        // 10  Posición de la última "o"
s.indexOf( "o", 3 )         // 10  Posición de la primera "o" después del 3er caracter
s.split(", ")               // ["Hola", "Mundo"]   Crea un array a partir de la cadena
s.replace( "a", "o" )       // "Holo, mundo"  Reemplaza las "a" por "o"
s.toUpperCase()             // "HOLA, MUNDO"

Con ECMAScript5 puedes acceder a los caracteres de una cadena como si fuera un array: s[1] === "o"

Cadenas

Tipos de datos

Las cadenas, son un tipo primitivo e inmutable de datos.

 

Cuando decimos que es inmutable, significa que no podemos cambiar su valor. Con los números esto resulta intuitivo, ya que no tiene sentido modificar el valor del número 3, por ejemplo. Pero con cadenas, no es tan sencillo de entender.

var s = "hola";
s.toUpperCase();   // "HOLA"  Devuelve la cadenas en mayúsculas.
console.log( s );  // "hola"  No ha cambiado su valor original.

// Lo que hace en realidad s.toUpperCase() es devolver un new String()

Booleanos

Tipos de datos

Pueden valer true o false. Son generalmente el resultado de comparaciones: a === 4; Si no realizas comparación estricta, se produce coherción de datos: falsy values

undefined == false  // true
null == false       // true
0 == false          // true
NaN == false        // true
"" == false         // true

typeof false === "boolean"

null y undefined

Tipos de datos

null es una palabra reservada para indicar la ausencia de valor.

typeof null === "object"

typeof undefined === "undefined"

undefined es una palabra reservada que va un paso más allá. Se usa para indicar que el valor no ha sido definido

Conversión de tipos

Tipos de datos

Primitivo a primitivo

undefined

null

true

false

""

"1.2"

"pepe"

0

3

NaN

Infinity

A cadena:

"undefined"

"null"

"true"

"false"

""

"1.2"

"pepe"

"0"

"3"

"NaN"

"Infinity"

A número:

NaN

0

1

0

0

1.2

NaN

0

3

NaN

Infinity

A booleano:

false

false

true

false

false

true

true

false

true

true 
true

Conversión de tipos

Tipos de datos

Cuando se realiza una comparación normal (==), se produce una coherción (conversión) de datos entre los dos valores:

Las cadenas se convierten a números:

 

"0" == 0         // true

Los booleanos se convierten a números:

 

0 == false      // true

"0" == false    ???

// true

Conversión de tipos

Tipos de datos

A pesar de que JavaScript realizar muchos tipos de conversiones automáticas, nosotros también podemos forzarlas:

Number( "3" );    // 3
String( false );  // "false"
Boolean( [] );    // true
Object( 3 );      // new Number( 3 )

Conversión de tipos

Tipos de datos

También es posible forzar la conversión de un tipo de datos, empleando operadores:

x + ""   // Lo mismo que String( x )
+x       // Lo mismo que Number( x )
!!x      // Lo mismo que Boolean( x )

Historia

Principios básicos

Tipos de datos

Arrays

Objetos

Declaraciones vs expresiones

Funciones

Closures

Herencia prototípica

DRY, KISS, YAGNI, Patrones

A

Arrays

Un array es una colección ordenada de valores.

Cada valor es llamado elemento, y cada elemento tiene un índice para accede a él.

El valor del índice puede ir de 0 a 232-2 (4294967294).

Heredan muchos métodos de Array.prototype

En ECMAScript5, una cadena se comporta como un array de caracteres.

Crear un array

Cadenas y arrays

La manera más sencilla es crear un array con un literal

var vacio  = [];                  // Un array vacío
var primos = [2, 3, 5, 7, 11];    // Un array con 5 elementos
var mezcla = [ 1.1, true, "a", ]; // Un array con 3 elementos y trailing comma


// Un array no tiene por qué ser una constante
var pepe = 1;
var aPepe = [pepe, pepe+1, pepe+2, pepe+3];

// Podemos añadir huecos vacíos con undefined
var casa = ["hola",,,,3,{a:1},"adios"];

// Un array de 2 elementos undefined (la última coma no cuenta)
var undef = [,,];

Crear un array

Cadenas y arrays

Otra forma de crear un array es con el constructor

// Es lo mismo que a = [];
var a = new Array();

// Creamos un array con length 10
var a = new Array(10);

// Creamos un array definiendo sus elementos
var a = new Array(3, 2, 1, "a");

Acceso a los valores de un array

Cadenas y arrays

Se accede a cualquier elemento de un array, con el operador [], y poniendo delante el nombre del array.

nombreArray[ ínidice ];

var a = ["hola"],
    i = 2;

a[i] = 3;

a[i + 1] = "pepe";

a[a[i]] = a[0];

console.log( a[0] );

Acceso a los valores de un array

Cadenas y arrays

Un array es un tipo de objecto especializado. Para acceder a los elementos de un objeto podemos usar la misma notación.

 

El índice es convertido siempre a cadena:

var a = ["a","b",3,4];
console.log( a[1] );   // "b"

a[-1.2] = true // Crea la propiedad "-1.2" en el array

console.log( a );            // [ "a", "b", 3, 4 ]
console.log( a["-1.2"] );    // true 

Acceso a los valores de un array

Cadenas y arrays

Los índices de un array van de 0 a 2  - 1.

 

Los arrays pueden contener valores undefined. A esto se le llama "Sparse Array"

32

a = new Array(5); // Array vacío. a.length == 5.
a = [];           // Array vacío. a.length == 0.
a = [,,];         // Array con 2 undefined: la última coma no cuenta. a.length == 2.
a[1000] = 0;      // Array con 1000 undefined, y el último es 0. alength == 1001.

Longitud de un Array

Cadenas y arrays

La propiedad length de un Array, no es el número de elementos, sino el valor más alto de sus índices +1.

 

Si se cambia por error el valor de dicha propiedad, se eliminarán los elementos del array por encima de ese índice:

a = [1,2,3,4,5]; // 5 elementos.
a.length = 3;    // a ahora es [1,2,3].
a.length = 0;    // Borra todo. a ahora es [].

Manipulando valores

Cadenas y arrays

unshift

shift

pop

push

Cambian la longitud del Array. Mueve el valor de los índices.

delete a[1] no cambia la longitud ni mueve los índices. Crea Sparse Array.

Historia

Principios básicos

Tipos de datos

Arrays

Objetos

Declaraciones vs expresiones

Funciones

Closures

Herencia prototípica

DRY, KISS, YAGNI, Patrones

O

Objetos

Historia

Principios básicos

Tipos de datos

Arrays

Objetos

Declaraciones vs expresiones

Funciones

Closures

Herencia prototípica

DRY, KISS, YAGNI, Patrones

D

Declaraciones vs expresiones

Las declaraciones hacen cosas:

Las expresiones producen valores:

var nombre = "Pepe";
8 * 4;

Historia

Principios básicos

Tipos de datos

Arrays

Objetos

Declaraciones vs expresiones

Funciones

Closures

Herencia prototípica

DRY, KISS, YAGNI, Patrones

F

Funciones

Historia

Principios básicos

Tipos de datos

Arrays

Objetos

Declaraciones vs expresiones

Funciones

Closures

Herencia prototípica

DRY, KISS, YAGNI, Patrones

C

Closures

Historia

Principios básicos

Tipos de datos

Arrays

Objetos

Declaraciones vs expresiones

Funciones

Closures

Herencia prototípica

DRY, KISS, YAGNI, Patrones

H

Herencia prototípica

Historia

Principios básicos

Tipos de datos

Arrays

Objetos

Declaraciones vs expresiones

Funciones

Closures

Herencia prototípica

DRY, KISS, YAGNI, Patrones

D

DRY, KISS, YAGNI, Patrones

¡Gracias!

@alfonsomartinde

Made with Slides.com