MANTENIBILIDAD Y CONFIABILIDAD DE LOS SISTEMAS MECANICOS
Javascript
1. www.interlat.co
–
info@interlat.co
-‐
h2p://www.facebook.com/interlat
-‐
www.twi2er.com/interlat
-‐
PBX:
57(1)
658
2959
-‐
Bogotá
-‐
Colombia
Aula
Virtual:
h2p://www.interlat.co/moodle/
Conferencista:
Carlos Alonso Pérez
País: España
Módulo III:
Móvil Apps Desarrollo en
Java Script
2. Antes
de
empezar...
Presentaciones
• Nombre
• Edad
• Estudios
• ¿A
qué
te
dedicas?
• ¿Por
qué
estás
aquí?
• ¿Qué
esperas
de
este
curso?
• ¿Qué
experiencia
Wenes
con
JS,
HTML
y
CSS?
5. Índice
de
contenidos
• Introducción
y
entorno
de
desarrollo
• Conceptos
de
programación
básicos
• Conceptos
de
programación
avanzados
• Javascript
en
navegadores
Web
• DOM
• Eventos
• AJAX
• Seguridad
• Frameworks
8. Introducción
• ¿Qué
sabemos
de
Javascript?
– Historia
– ¿Es
un
lenguaje
de
programación?
¿de
scripWng?
¿un
subconjunto
de
Java?
– ¿Estructurado
u
OO?
– ¿Compilado
o
interpretado?
– ¿ImperaWvo,
funcional
o
híbrido?
– ¿Fuerte
o
débilmente
Wpado?
– ¿Dinámico?
– ¿Cuáles
son
sus
entornos
de
ejecución?
– ¿Sencillo
o
diicil?
– ¿Potente?
– ¿Tiene
errores?
– ¿Tiene
buena
o
mala
reputación?
18. Estructura
léxica
• Juego
de
caracteres:
Unicode
case
sensiWve
• Comentarios
C
• Literales
• Sentencias
/*
* Literales
*/
12
1.2
“Hello World!”
/*
* Sentencias
*/
var a = 1;
19. Estructura
léxica
• IdenWficadores
– i, my_variable, _dummy, $str, sí, π
• Palabras reservadas
– break delete case do catch else continue false
debugger finally default for function return typeof
if switch var in this void instanceof throw while new
true with null try
20. Estructura
léxica
• ;
es
opcional!!
/*
* Comportamiento esperado
*/
1 + 2
“hola mundo!”
/*
* Comportamiento inesperado!
*/
var f = 2
1 + f
(2 + 3) * 2
24. Number:
Precisión
Enteros:
Hasta
15
dígitos Float:
Tanto
como
sea
posible
999999999999999
9999999999999999
0.3 - 0.2 == 0.2 - 0.1
0.2 - 0.1
0.3 - 0.2
// Solución toFixed(n)
(0.3 - 0.2).toFixed(2)
Problema
de
todos
los
sistemas
binarios!!
26. undefined
y
null
• undefined
=>
no
inicializado
• null
=>
no
hay
objeto
o
valor
27. Booleanos
• true
y
false
• Tabla
de
verdad:
– false
=>
undefined,
null,
0,
-‐0,
NaN
y
“”
– true
=>
Todo
lo
demás
28. Detectando
Wpos
• Operador
typeof
/*
* Detección de tipos
*/
typeof 2
typeof 2.33
typeof “Hola Mundo!”
typeof undefined
typeof true
typeof null // Es un objeto!!
29. Tipos
proporcionados
por
JS
• Fechas
y
horas
• El
objeto
global
• Wrapper
objects
• Conversión
de
Wpos
(CasWng)
30. Fechas
y
horas
• Clase
Date
• Documentación:
– h2ps://developer.mozilla.org/en-‐US/docs/JavaScript/Reference/Global_Objects/Date
/* Ejemplo uso de fechas */
var now = new Date();
var future = new Date(now.getTime() + 300000);
future - now;
31. Fechas
y
horas:
Ejercicio!
• Calcular
el
número
de
días
que
han
pasado
desde
mi
nacimiento
el
19
-‐
Marzo
-‐
1985.
• Documentación:
– h2ps://developer.mozilla.org/en-‐US/docs/JavaScript/Reference/Global_Objects/Date
32. Fechas
y
horas:
Ejercicio!
• Calcular
el
número
de
días
que
han
pasado
desde
mi
nacimiento
el
19
-‐
Marzo
-‐
1985.
• Documentación:
– h2ps://developer.mozilla.org/en-‐US/docs/JavaScript/Reference/Global_Objects/Date
/*
* Solución: 10084.7249...
*/
var now = new Date();
var carlos = new Date(1985, 2, 19);
var millis = now - carlos;
millis / 1000 / 60 / 60 / 24;
33. El
objeto
global
• Creado
al
inicializar
el
intérprete
JS
• Es
nuestro
contexto
de
ejecución
(this)
• Proporciona
métodos
– isNaN(),
isFinite(),
...
/*
* El objeto global nos permite usar sus métodos
* directamente, sin usar this
*/
isNaN(“hola”);
this.isNaN(“hola”);
34. El
objeto
global
• Proporciona
Constructores:
– Date,
Object,
...
• Almacena
nuestras
variables
globales
/*
* Constructores
*/
var now = new this.Date();
now;
/*
* Almacena variables
* globales
*/
var now = new Date();
this.now;
35. Wrapper
Objects
/*
* Ejemplo 1
*/
var s = “Hola Mundo!”;
console.log(typeof s);
s.charAt(0);
/*
* Ejemplo 2
*/
var s = “Hola Mundo!”;
s.my_dummy_var = 56;
s.my_dummy_var;
• Conversión
automáWca
entre
Wpos
primiWvos
y
su
correspondiente
‘wrapper
object’
36. Wrapper
Objects
/*
* Ejemplo 1
*/
var s = new String(“Hola!”);
console.log(typeof s);
s.my_dummy_var = 56;
s.my_dummy_var;
/*
* Ejemplo 2
*/
var n = new Number(5);
console.log(5 == n);
5 === n;
• Conversión
automáWca
entre
‘wrapper
objects’
y
su
Wpo
primiWvo
40. Variables:
Declaración
/*
* Declaración e inicialización
*/
var i; // Declaración simple
var i, j, k; // Declaración múltiple
var i = 0; // Inicialización simple
var i = 0, j = 1, k = 2; // Inicialización múltiple
var a, b = “hola”; // Declaración + inicialización
41. Variables:
Redeclaración
y
omisión
/*
* Redeclaración
*/
var a = 1;
var a = 2;
a; // 2
/*
* Redeclaración
*/
var a = 1;
var a;
a; // 1
/*
* Omisión
*/
a = 1;
a // 1
42. Variables:
Scope
var scope = “global”;
function checkscope() {
scope = “local”;
}
checkscope();
scope; // local
• Global:
Variables
disponibles
en
cualquier
sección
del
código.
var scope = “global”;
function checkscope() {
var scope = “local”;
}
checkscope();
scope; // global
• Local:
Variables
definidas
dentro
de
una
función.
• Eclipsan
variables
globales
con
el
mismo
nombre.
43. Variables:
Scope
• El
problema
de
definir
variables
omiWendo
‘var’.
scope = “global”;
function checkscope() {
scope = “local”;
localvar = “local”;
}
checkscope();
scope; // local => ¡¡Ha sido modificada!!
localvar; // local => ¡¡Está definida!!
44. Variables:
Scope
• Función:
CaracterísWca
de
JS.
La
variable
está
disponible
en
todo
el
cuerpo
de
la
función.
No
sólo
en
el
bloque
donde
se
define.
function checkscope() {
if (true) {
var j = 1;
if (true) {
var k = 2;
}
}
console.log(j); // 1
console.log(k); // 2
}
checkscope();
45. Variables:
Scope
• Variable
hoisWng:
Otra
caracterísWca
de
JS.
¡¡Las
variables
definidas
en
una
función
están
disponibles
antes
incluso
de
ser
definidas!!
var scope = “global”;
function checkscope() {
console.log(scope); // undefined
var scope = “local”;
console.log(scope); // local
}
checkscope();
46. Objetos
• Tipo
de
dato
fundamental
de
JS
• Colección
no
ordenada
de
propiedades
con
nombre
y
valor
• Dinámicos
47. Objetos:
El
‘prototype’
• Todas
las
clases
JS
Wenen
un
prototype
asociado
que
define
sus
atributos
y
métodos.
• Todos
los
objetos
de
una
clase
tendrán
todos
los
atributos
y
métodos
de
su
prototype
y
pueden,
además,
tener
otros
atributos
y
métodos
propios.
48. Objetos:
Creación
• Literal
var empty = {};
var point = {x:1, y:3};
var book = {
title: "The title",
author: {
name: "author name",
surname: "author surname"
}};
49. Objetos:
Creación
• Operador
‘new’
var o = new Object();
var d = new Date();
• Object.create();
var o = Object.create(Object.prototype);
var p = Object.create(Object.prototype, { x: 1, y: 2});
var d = Object.create(Date.prototype); // Excepción!!
50. Objetos:
Propiedades
• Tienen
un
nombre,
un
valor
y
atributos.
• Son
accesibles
con
notación
de
punto
(.)
o
corchetes
([])
• Se
pueden
añadir
o
eliminar
en
Wempo
de
ejecución.
• Pueden
ser
propias
o
heredadas.
51. Objetos:
Propiedades
• Añadiendo
propiedades
var o = {};
o.first_prop = “first”;
o[“second_prop”] = “second”;
• Accediendo
a
propiedades
o[“first_prop”]; // first
o.second_prop; // second
53. Propiedades:
Ejercicio!
• Crear
una
función
que
reciba
tres
parámetros,
un
objeto,
el
nombre
de
una
propiedad
y
un
valor.
• La
función
debe
comprobar
si
el
objeto
Wene
una
propiedad
con
ese
nombre
y
si
la
Wene
retornar
el
valor
y
sino
definirla,
asignar
el
valor
recibido
en
el
tercer
parámetro
y
retornarlo.
54. Propiedades:
Ejercicio!
• Crear
una
función
que
reciba
tres
parámetros,
un
objeto,
el
nombre
de
una
propiedad
y
un
valor.
• La
función
debe
comprobar
si
el
objeto
Wene
una
propiedad
con
ese
nombre
y
si
la
Wene
retornar
el
valor
y
sino
definirla,
asignar
el
valor
recibido
en
el
tercer
parámetro
y
retornarlo.
function f(obj, property, value) {
if (!obj[property]) {
obj[property] = value;
}
return obj[property];
}
55. Propiedades:
Detección
• Operador
‘in’:
Detecta
propiedades
propias
o
heredadas.
var o = { x: 1 };
“x” in o; // true
“y” in o; // false
“toString” in o; // true
• Método
hasOwnProperty():
Detecta
propiedades
propias,
no
heredadas,
sean
enumerables
o
no.
var o = { x: 1 };
o.hasOwnProperty(“x”); // true
o.hasOwnProperty(“y”); // false
o.hasOwnProperty(“toString”); // false
56. Propiedades:
Detección
• Método
propertyIsEnumerable():
Detecta
propiedades
propias
y
enumerables
var o = { x: 1 };
o.propertyIsEnumerable(“x”); // true
o. propertyIsEnumerable(“y”); // false
o. propertyIsEnumerable(“toString”); // false
57. Propiedades:
Enumeración
• Bucle
for/in:
Propiedades
propias
o
heredadas
enumerables
var o = { x: 1, y: 2, z: 3 };
for(p in o) {
console.log(p);
console.log(o[p]);
}
• Método
Object.keys(objeto):
Retorna
un
Array
con
las
propiedades
propias
y
enumerables
• Método
Object.getOwnPropertyNames(objeto):
Retorna
un
Array
con
las
propiedades
propias,
sean
enumerables
o
no
58. Propiedades:
ComparaWva
Método
de
Acceso
Propias Heredadas Enumerables
No
enumerables
Acceso
simple
(.
ó
[]) Sí Sí Sí Sí
Operador
in Sí Sí Sí Sí
Método
hasOwnProperty()
Sí No Sí Sí
Método
propertyIsEnumerable
()
Sí No Sí No
Bucle
for/in Sí Sí Sí No
Object.keys() Sí No Sí No
Object.getOwnProp
ertyNames()
Sí No Sí Sí
59. Accessor
properWes
• Consultar
o
asignar
una
‘accessor
property’
significa
la
ejecución
del
método
get/set
correspondiente
var o = {
_a: 3,
get a() {
return this._a;
},
set a(value) {
this._a = value;
}
};
o.a = 4;
o.a;
60. Propiedades:
Atributos
• Value:
El
propio
valor
de
la
propiedad.
• Writable:
Determina
si
es
modificable
o
no.
• Get:
Función
ge2er
• Set:
Función
se2er.
• Enumerable:
Determina
si
la
propiedad
es
enumerable
o
no.
• Configurable:
Determina
si
los
estos
atributos
pueden
ser
modificados
o
no.
62. Propiedades:
Manejando
atributos
• Método
Object.getOwnPropertyDescriptor():
Retorna
un
objeto
que
describe
los
atributos
de
la
propiedad.
/*
* Obtener Property Descriptor
* para una propiedad
*/
var o = { x: 1, y: 2 };
Object.getOwnPropertyDescriptor(o, “x”);
63. Propiedades:
Manejando
atributos
• Método
Object.defineProperty():
Crea
o
modifica
los
atributos
de
una
propiedad
si
ésta
es
propia
y
configurable.
var descriptor = { value: 1, writable:
true, enumerable: false, configurable:
true};
var o = {};
Object.defineProperty(0, “x”, descriptor);
o.x; // 1
Object.keys(o); // []
64. Manejando
atributos:
Ejercicio!
• Dada
esta
inicialización,
¿se
podría
cambiar
el
valor
de
o.x?
¿Y
el
de
o1.x?
¿Cómo?
• Pista:
¿Cuál
es
el
valor
por
defecto
del
atributo
configurable?
var o = {};
Object.defineProperty(o, “x”,
{ value: 1, writable: false });
var o1 = { x: 1 };
Object.defineProperty(o1, “x”,
{ writable: false });
65. Manejando
atributos:
Solución
• La
solución
está
en
el
atributo
configurable
de
la
propiedad
y
los
valores
por
defecto,
que
dependen
del
método
que
usemos
para
definir
la
propiedad.
• Definición
literal:
Todos
los
atributos
=
true.
• Definición
usando
Object.defineProperty:
Todos
los
atributos
no
especificados
=
false.
Object.defineProperty(o, “x”,
{ value: 2 }); // Error!! x no es configurable
Object.defineProperty(o1, “x”,
{ value: 2 }); // OK
66. Arrays
• Creación
var empty = [];
var fill = [1, 2, 3, 4];
var empty2 = new Array();
var withSize = new Array(10);
var fill2 = new Array(1, 2, 3, 4);
• No
Wpados
var misc = [1, “hola”, true, , {}, []];
var misc2 = new Array(1, “hola”, true, {}, []);
67. Arrays
• Crecen
dinámicamente
var a = [];
a[3] = “hola”;
a;
• Son
objetos,
por
tanto
admiten
propiedades!!
var a = [];
a.hola = “hola”;
a.hola;
68. Funciones
• Son
Wpos
primiWvos:
• Se
pueden
usar
como
variables
• Se
pueden
pasar
como
argumentos
a
otras
funciones
• Pueden
ser
el
retorno
de
otra
función
• Se
les
pueden
asignar
propiedades
e
incluso
invocar
métodos
en
ellas.
69. Funciones
• Definición
// Como expresión
function f(x) {
return x + 1;
}
// Como sentencia
var f = function(x) {
return x + 1;
}
// Anidada
function hypotenuse(a, b) {
function square(x) { return x * x; };
return Math.sqrt(square(a) + square(b));
}
70. Funciones:
Scope
léxico
• Tienen
acceso
a
todas
las
variables
definidas
en
el
bloque
donde
son
definidas.
function a(x) {
var y = “y”;
function b() {
console.log(x + “ “ + y + “ “ + z); // x y z
}
var z = “z”;
b();
}
a(“x”);
71. Métodos
• Son
funciones
que
son
propiedades
de
algún
objeto.
• Se
ejecutan
en
el
contexto
del
objeto.
var o = {
m: function() {
console.log(this === o);
}
}
72. Métodos
con
funciones
anidadas
• Fuente
común
de
errores
debido
al
contexto
(this).
var o = {
m: function() {
console.log(this === o); // true
function f() {
console.log(this === o); // false
console.log(this); // Es el objeto global!!
}
f();
}
}
o.m();
73. Métodos
con
funciones
anidadas
• La
solución
es
el
uso
del
scope
léxico
var o = {
m: function() {
var self = this;
function f() {
console.log(self === o); // true
}
f();
}
}
o.m();
75. Funciones:
Ejercicio!
• ¿Los
argumentos
en
JS
se
pasan
por
valor
o
por
referencia?
¿Y
sin
son
objetos?
/*
* Solución
*/
function f (value, object) {
value ++;
object.x ++;
}
var o = { x: 1 };
var v = 1;
f(v, o);
console.log(o);
console.log(v);
76. Funciones:
Argmentos
• No
se
comprueba
ni
el
Wpo
ni
el
número
function a(x, y) {
console.log(“Función ejecutada correctamente”);
}
a(1); // Con un argumento menos
a(1, 2, 3); // Con un argumento mas
78. Funciones:
Argmentos
• Argumentos
extra:
‘varargs
funcWons’.
• JS
proporciona
a
todas
las
funciones
un
array
‘arguments’
• Nos
permite
comprobar
si
una
función
se
ha
invocado
con
el
número
correcto
de
argumentos.
• Nos
permite
definir
funciones
que
trabajen
sobre
un
número
variable
de
argumentos.
function f(x, y, z) {
if (arguments.length != 3) {
throw new Error(“Wrong arguments number”);
}
// ...
}
79. Funciones:
Ejercicio!
• Definir
una
función
que
retorne
el
número
máximo
de
todos
los
que
recibe
como
argumentos.
• La
función
no
debe
definir
ningún
argumento:
• function max() { ... }
• Pista:
Podéis
usar
Number.INFINITY
y
Number.NEGATIVE_INFINITY
80. Funciones:
Ejercicio!
• Definir
una
función
que
retorne
el
número
máximo
de
todos
los
que
recibe
como
argumentos.
• La
función
no
debe
definir
ningún
argumento:
• function max() { ... }
• Pista:
Podéis
usar
Number.INFINITY
y
Number.NEGATIVE_INFINITY
function max(/* ... */) {
var max = Number.NEGATIVE_INFINITY;
for (var i = 0 ; i < arguments.length ; ++i) {
if (arguments[i] > max) {
max = arguments[i]
}
}
return max;
}
console.log(max());
console.log(max(1, 2, 1000, 3));
81. Funciones:
Propiedades
• Las
funciones
son
objetos,
por
tanto
pueden
tener
propiedades.
function uniqueValue() {
return uniqueValue.c ++;
}
uniqueValue.c = 1;
console.log(u());
console.log(u());
console.log(u());
82. Funciones:
call
y
apply
• call
y
apply
son
métodos
de
las
funciones
que
nos
permiten
invocarlas
indirectamente,
¡como
si
fueran
métodos
de
otros
objetos!.
• Se
diferencian
en
la
forma
de
recibir
los
argumentos.
var num = { value: 1 };
function sum(value) {
return this.value + value;
}
console.log(sum.apply(num, [1]));
console.log(sum.call(num, 2));
83. Clases
• Clase
en
JS:
Conjunto
de
objetos
que
heredan
propiedades
del
mismo
protoWpo.
function range(from, to) {
var r = Object.create(range.prototype);
r.from = from;
r.to = to;
return r;
}
range.prototype = {
includes: function(x) {
return this.from <= x && x <= this.to;
},
toString: function() {
return “(“ + this.from + “..” + this.to + “)”;
}
};
var r = range(1, 3);
console.log(r.includes(2));
r.toString();
84. Clases:
Constructores
• En
JS
se
define
una
clase
mediante
una
función
constructor
y
su
prototype.
function Range(from, to) {
this.from = from;
this.to = to;
}
Range.prototype = {
includes: function(x) {
return this.from <= x && x <= this.to;
},
toString: function() {
return “(“ + this.from + “..” + this.to + “)”;
}
};
var r = new Range(1, 3);
console.log(r.includes(2));
r.toString();
85. Clases:
operador
‘new’
• Convierte
una
función
simple
en
un
constructor:
• El
intérprete
creará
un
nuevo
objeto.
• Lo
converWrá
en
el
contexto
actual
(this).
• Le
asignará
la
propiedad
prototype
al
prototype
de
la
función
• Lo
usará
como
retorno
de
la
función
(constructor).
86. Operador
‘new’:
Ejercicio!
• ¿Qué
ocurriría
si,
por
error,
invocamos
un
constructor
sin
el
operador
new?
• ¿Qué
objeto
se
creará?
• ¿Qué
efecto
tendrá
el
código
del
constructor?
• ¿Cuál
será
el
valor
retornado?
87. Operador
‘new’:
Ejercicio!
• ¿Qué
ocurriría
si,
por
error,
invocamos
un
constructor
sin
el
operador
new?
• ¿Qué
objeto
se
creará?
• ¿Qué
efecto
tendrá
el
código
del
constructor?
• ¿Cuál
será
el
valor
retornado?
• No
se
creará
ningún
objeto
nuevo.
• El
contexto
desde
el
que
se
invoque
la
función
sufrirá
las
modificaciones
resultantes
del
código
del
constructor.
• El
valor
de
retorno
será
undefined.
88. Clases:
Herencia
• Heredar
en
JS
significa
que
el
protoWpo
de
la
función
constructor
de
la
clase
hija
es
un
objeto
de
la
clase
padre.
• La
función
constructor
de
la
clase
padre
Wene
como
prototype
un
objeto
de
su
clase
padre.
• La
función
constructor
de
Object
es
la
única
del
lenguaje
cuyo
prototype
es
null.
• Así
se
consWtuye
la
cadena
de
protoWpos
(prototype
chain)
Object()
proto
=
null
Parent()
proto
=
Object
Child()
proto
=
Parent
89. Clases:
Herencia
function Parent() {
}
Parent.prototype = {
sayHello: function() {
console.log("Hello");
}
};
function Child() {
}
Child.prototype = new Parent();
Child.prototype.sayGoodbye =
function() {
console.log("Goodbye");
};
var child = new Child();
child.sayHello();
child.sayGoodbye();
child.toString();
Object()
proto
=
null
Parent()
proto
=
Object
Child()
proto
=
Parent
90. Detectando
clases
• Mediante
el
prototype:
Un
objeto
es
de
una
clase
si
su
prototype
y
el
de
su
constructor
son
el
mismo.
• Los
objetos
de
una
clase
no
Wenen
propiedad
prototype
definida.
La
propiedad
prototype
es
de
la
función
constructora.
// En el ejemplo anterior...
var child = new Child();
child.prototype; // undefined!!
var child = new Child();
Object.getPrototypeOf(child);
// Retorna el objeto Parent que asignamos como
// prototype a la función Child y extendimos
91. Detectando
clases:
Ejercicio!
• Escribir
una
función
que
reciba
dos
argumentos,
un
objeto
y
un
constructor
e
indique
si
el
objeto
es
de
ese
Wpo
o
de
algún
ancestro
de
ese
Wpo.
92. Detectando
clases:
Ejercicio!
• Escribir
una
función
que
reciba
dos
argumentos,
un
objeto
y
un
constructor
e
indique
si
el
objeto
es
de
ese
Wpo
o
de
algún
ancestro
de
ese
Wpo.
function isKindOfClass(object, klazz) {
var ret = false;
while (!ret && object) {
ret = Object.getPrototypeOf(object) === klazz.prototype;
object = Object.getPrototypeOf(object);
}
return ret;
}
function Test() {
}
var t = new Test();
isKindOfClass(t, Test); // true
isKindOfClass(t, Object); // true
isKindOfClass(t, String); // false
93. Detectando
clases
• Operador
instanceof:
Detecta
si
un
objeto
es
instancia
de
una
clase
o
ancestro.
Exactamente
lo
mismo
que
acabamos
de
implementar!!
// En el ejemplo anterior...
var child = new Child();
child instanceOf Parent; // true
child instanceOf Object; // true
child instanceOf String; // false
94. Detectando
clases
• Propiedad
constructor:
Propiedad
que
Wenen
todos
los
protoWpos,
aunque
JS
no
siempre
puede
asignarla.
Parent()
prototype
Constructor
constructor
Prototype
sayHello:
...
new
Parent()
Instancias
new
Parent()
hereda
hereda
95. Detectando
clases
• JS
no
puede
asignarla
automáWcamente.
function Parent() {
}
Parent.prototype = {
constructor: Parent,
sayHello: function() {
console.log("Hello");
}
};
• JS
sí
puede
asignarla
automáWcamente.
function Parent() {
}
Parent.prototype.sayHello = function() {
console.log("Hello");
};
(new Parent()).constructor;
96. Modificación
dinámica
de
clases
• JS
permite
modificar
los
objetos
prototype
de
cualquier
constructor
en
Wempo
de
ejecución
y
la
modificación
afectará
incluso
a
los
objetos
ya
existentes.
function Parent() {
}
Parent.prototype = {
sayHello: function() {
console.log("Hello");
}
};
var p = new Parent();
Parent.prototype.sayHi = function() {
console.log(“Hi”);
};
p.sayHi();
97. Modificación
dinámica
de
clases:
Ejercicio!
• Modificar
la
clase
Number
y
añadirle
un
método
que
nos
indique
si
su
valor
es
par
o
no.
• Mirad
la
documentación
de
Number
y
su
prototype
98. Modificación
dinámica
de
clases:
Ejercicio!
• Modificar
la
clase
Number
y
añadirle
un
método
que
nos
indique
si
su
valor
es
par
o
no.
• Mirad
la
documentación
de
Number
y
su
prototype
/*
* Solución
*/
Number.prototype.even = function() {
return this.valueOf() % 2 == 0;
}
var n = 4;
n.even();
99. Métodos
estáWcos
• No
existen
en
JS,
pero
es
tan
flexible
que
podemos
simularlos
como
métodos
de
la
función
constructora.
Parent.buildNew = function() {
return new Parent();
}
var p = Parent.buildNew();
101. Scope
Chain
• Conceptos:
– Scope:
Conjunto
de
líneas
de
código
en
las
que
una
variable
está
definida.
Puede
ser:
• Global:
Variables
globales,
que
están
definidas
en
todo
el
programa.
• Local:
Variables
definidas
en
la
función
que
son
declaradas
y
en
las
funciones
anidadas
dentro
de
esa
función.
102. Scope
Chain
• JS
almacena
las
variables
con
scope
local
para
cada
fragmento
de
código
como
propiedades
de
un
objeto
interno.
• El
scope
chain
es
una
cadena
(lista)
de
objetos
que
definen
las
variables
que
están
en
scope.
• Cada
fragmento
de
código
Wene
un
scope
chain
asociado.
• Cuando
JS
necesita
buscar
una
variable
recorre
el
scope
chain
de
forma
ordenada
hasta
que
encuentra
algún
objeto
de
la
cadena
que
define
la
variable
o
la
cadena
termina
y
lanzaría
un
ReferenceError.
• Cuando
una
función
es
invocada,
un
nuevo
objeto
se
añade
al
scope
chain
con
las
variables
locales
de
la
función.
103. Scope
Chain
var a = 1;
function f(c) {
var b = 2;
// Scope chain 2
}
// Scope chain 1
f(3);
• Ejemplo:
{ a: 1,
f: function() }
{ a: 1,
f: function() }
{ c: 3,
b: 2 }
Scope
Chain
1
Scope
Chain
2
• El
proceso
de
resolución
de
variables
sigue
la
cadena
en
el
senWdo
de
las
flechas.
104. Scope
Chain
var a = 1;
function f(c) {
var b = 2;
function s(d) {
// Scope chain(i)
return b + c;
}
return s(4);
}
for (var i = 0 ; i < 3 ; ++i) {
f(i);
}
• Ejemplo
con
funciones
anidadas:
{ a: 1,
f: function(),
i: i }
{ c: i,
b: 2,
s: func }
Scope
Chain(i)
{ d: 4 }
105. Scope
chain:
Ejercicio!
var a = 1;
function f(c) {
var b = 2;
function s(d) {
// Scope chain(i, j)
return b + c + d;
}
return s(j);
}
for (var i = 0 ; i < 3 ; ++i) {
for (var j = 0 ; j < 3 ; ++j) {
f(i);
}
}
• Dibujar
el
Scope
Chain
que
exisWrá
en
el
punto
del
comentario.
• Recordad:
• Que
ese
Scope
Chain
dependerá
de
las
variables
i
y
j.
• Que
cada
vez
que
una
función
es
invocada,
sus
funciones
anidadas
son
definidas
nuevamente
• Que
solo
se
añade
un
nuevo
objeto
al
Scope
Chain
cuando
ocurre
una
invocación
de
una
función,
pero
el
estado
del
resto
de
objetos
del
Scope
Chain
puede
variar
en
cualquier
momento
(nuevas
variables
o
cambio
de
valor
de
variables
ya
existentes.)
106. Scope
chain:
Solución!
{ a: 1,
f: function(),
i: i,
j: j }
{ c: i,
b: 2,
s: func }
Scope
Chain(i,
j)
{ d: j }
var a = 1;
function f(c) {
var b = 2;
function s(d) {
// Scope chain(i, j)
return b + c + d;
}
return s(j);
}
for (var i = 0 ; i < 3 ; ++i) {
for (var j = 0 ; j < 3 ; ++j) {
f(i);
}
}
• ¿Dudas?
¿Preguntas?
¿RepeWmos?
107. Closures
• JS
usa
Scope
Léxico,
es
decir,
las
funciones
son
ejecutadas
usando
el
scope
existente
cuando
fueron
definidas,
no
cuando
son
invocadas.
• Para
implementar
Scope
Léxico,
cada
función
guarda
internamente
el
código
a
ejecutar
y
una
referencia
al
scope
chain
existente
cuando
se
define.
• Objeto
función
+
Scope
Chain
=
Closure
108. Closures
• Mismo
Scope
Chain
var scope = “global scope”;
function checkscope() {
var scope = “local scope”;
function f() {
return scope;
}
return f();
}
checkscope(); // “local scope”
• Diferente
Scope
Chain
var scope = “global scope”;
function checkscope() {
var scope = “local scope”;
function f() {
return scope;
}
return f;
}
a = checkscope();
a(); // “local scope”
• Sorprendidos,
¿verdad?
111. Closures:
Private
properWes
• Un
posible
uso
de
las
closures
es
definir
propiedades
privadas
en
objetos.
function Test() {
var my_private = “private”;
Object.defineProperty(this, “my_private”, {
get: function() {
return my_private;
}
});
}
var t = new Test();
t.my_private = “not private”; // No tiene efecto o da error
t.my_private; // private
112. Closures:
Ejercicio!
• Definir
una
clase
Counter
que
tenga
únicamente
dos
métodos
públicos
y
ninguna
propiedad:
• count():
Devuelve
el
número
de
llamadas
recibidas
a
esta
función.
• reset():
Pone
a
0
el
contador
113. Closures:
Ejercicio!
• Definir
una
clase
Counter
que
tenga
únicamente
dos
métodos
públicos
y
ninguna
propiedad:
• count():
Devuelve
el
número
de
llamadas
recibidas
a
esta
función.
• reset():
Pone
a
0
el
contador
function Counter() {
var counter = 0;
this.count = function() {
counter ++;
return counter;
};
this.reset = function() {
counter = 0;
};
}
114. Subclases
• Hasta
ahora,
cuando
necesitamos
extender
una
clase,
simplemente
encadenamos
sus
protoWpos.
• ¿Qué
ocurre
cuando
necesitamos
inicializar
el
padre?
function Parent() {
this.initialized = true;
}
Parent.prototype = {
initialized: false,
sayHello: function() {
if (this.initialized) {
console.log("Hello");
}
}
};
function Child() {
}
Child.prototype = new Parent();
Child.prototype.sayGoodbye =
function() {
console.log("Goodbye");
};
var c = new Child();
child.sayHello();
115. Subclases
• La
solución
es
‘aplicar’
el
constructor
del
padre
a
nuestro
contexto.
function Child() {
Parent.apply(this, arguments);
}
116. Subclases:
Ejercicio!
• En
el
código
de
ejemplo,
¿cómo
haríais
para
que
la
llamada
a
sayHello
en
el
hijo
ejecute
también
sayHello
en
el
padre?
function Parent() {
}
Parent.prototype = {
sayHello: function() {
console.log("Hello");
}
};
function Child() {
}
Child.prototype = new Parent();
Child.prototype.sayHello = function() {
console.log(" from child");
};
var c = new Child();
child.sayHello();
117. Subclases:
Solución!
• Igual
que
invocamos
al
constructor
de
la
función
padre
con
apply,
hacemos
lo
mismo
con
la
función
sayHello,
referenciándola
a
través
de
su
prototype.
Child.prototype.sayHello = function() {
Parent.prototype.sayHello.apply(this, arguments);
console.log(" from child");
};
118. Clases
Abstractas
function Parent() {
}
Parent.prototype = {
sayHello: function() {
throw new Error(“Abstract method!”);
}
};
function Child() {
}
Child.prototype = new Parent();
Child.prototype.sayHello = function() {
console.log("Hello");
};
var c = new Child();
child.sayHello();
119. Comparación
de
objetos
• En
Javascript
los
objetos
se
comparan
por
referencia
si
se
usan
los
comparadores
==
o
===
new Number(3) == new Number(3); // false
120. Comparación
de
objetos:
Ejercicio!
• ¿Cómo
podemos
conseguir
que
los
objetos
Number
sean
comparados
por
valor?
Implementar
la
solución
• Pista:
En
otros
lenguajes
como
Java,
todas
las
clases
definen
un
método
equals().
121. Comparación
de
objetos:
Ejercicio!
• ¿Cómo
podemos
conseguir
que
los
objetos
Number
sean
comparados
por
valor?
Implementar
la
solución
• Pista:
En
otros
lenguajes
como
Java,
todas
las
clases
definen
un
método
equals().
Number.prototype.equals = function(obj) {
if (!obj instanceof Number) {
return false;
}
return this.valueOf() == obj.valueOf();
};
(new Number(3)).equals(new Number(3));
122. Módulos
• Necesitamos
definir
módulos
si
queremos:
• Mantener
el
código
organizado.
• Poder
mantenerlo.
• ReuWlizarlo
• ...
• Pero
JS
no
proporciona
una
forma
estándar,
por
tanto
tenemos
que
diseñar
nuestra
propia
manera
de
hacerlo.
• ObjeWvo:
Definir
un
módulo
que
se
incluya
en
otros
programas
JS
y
no
altere
el
entorno.
• Minimizar
el
número
de
variables
globales
definidas.
123. Módulos
• Paso
1:
UWlizar
un
solo
objeto
como
namespace
/*
* Definición
*/
var collections = {};
collections.Set = function() {
//Constructor
};
collections.Set.prototype ...
collections.OrderedMap = function() {
//Constructor
}
collections.OrderedMap.prototype ...
/*
* Uso
*/
var s = new collections.Set(...);
// pseudo-import
var Set = collections.Set;
var s2 = new Set(...);
124. Módulos
• Paso
2:
UWlizar
funciones
como
namespace
privado
/*
* Definición
*/
var collections = {};
(function(){
collections.Set = function() {
//Constructor
};
collections.Set.prototype ...
collections.OrderedMap = function() {
//Constructor
}
collections.OrderedMap.prototype ...
var api_private_var;
function api_private_func(){};
})();
125. Módulos
• Paso
3:
Separar
cada
clase
en
un
archivo
/*
* collections/set.js
*/
var collections;
if (!collections) {
collections = {};
}
(function() {
collections.Set = function()
{
//Constructor
};
collections.Set.prototype ...
var set_private_var;
})();
/*
* collections/orderedmap.js
*/
var collections;
if (!collections) {
collections = {};
}
(function() {
collections.OrderedMap = function() {
//Constructor
}
collections.OrderedMap.prototype ...
var orderedMap_private_var;
})();
126. Módulos:
Ejercicio!
• Escribir
el
contador
con
count()
y
reset()
como
componente
de
un
módulo
llamado
uWls.
• Nota:
El
constructor
no
debe
contener
código.
127. Módulos:
Ejercicio!
• Escribir
el
contador
con
count()
y
reset()
como
componente
de
un
módulo
llamado
uWls.
• Nota:
El
constructor
no
debe
contener
código.
/*
* utils/counter.js
*/
var utils;
if (!utils) {
utils = {};
}
(function() {
var Counter = function() {
//Constructor
}
var value = 0;
Counter.prototype.count = function() {
value ++;
return value;
};
Counter.prototype.reset = function() {
value = 0;
};
utils.Counter = Counter;
})();
128. Javascript
en
navegadores
web
• Introducción
HTML
• Introducción
CSS
• El
navegador
web
como
entorno
• Uso
de
JS
en
la
web
129. HTML:
Estructura
• Partes
del
documento.
• DOCTYPE
• HTML
• HEAD
• BODY
• Estructura
de
árbol.
<!DOCTYPE html>
<html>
<head>
<!-- Cabecera del documento HTML -->
</head>
<body>
<!-- Cuerpo del documento HTML -->
</body>
</html>
130. HTML:
Elementos
Elemento Descripción Elemento Descripción
a Hipervínculo button Botón
code
Fragmento
de
código
fuente
hr
Separa
dos
bloques
con
una
línea
horizontal
input
Elemento
para
que
el
usuario
introduzca
datos
label
EWqueta
para
otro
elemento
p Párrafo table Tabla
td Celda
de
una
tabla textarea
Una
caja
de
texto
de
varias
líneas
th
Celda
de
cabecera
de
una
tabla
title El
„tulo
del
documento
tr Una
fila
de
una
tabla div Agrupa
elementos
131. HTML:
Elementos
<!DOCTYPE html>
<html>
<head>
<!-- Cabecera del documento HTML -->
</head>
<body>
<p>Esto es un parrafo de ejemplo</p>
<button>Esto es un boton</button>
<table>
<tr>
<th>Cabecera 1</th>
<th>Cabecera 2</th>
</tr>
<tr>
<td>Celda 1, 1</td>
<td>Celda 1, 2</td>
</tr>
<tr>
<td>Celda 2, 1</td>
<td>Celda 2, 2</td>
</tr>
</table>
</body>
</html>
132. HTML:
Elementos
• Todos
los
elementos
van
dentro
del
body.
• Todos
los
tags
deben
estar
balanceados.
• El
contenido
de
cada
elemento
va
entre
dos
tags,
apertura
y
cierre.
• Algunos
elementos
conWenen
texto,
otros
conWenen
otros
elementos.
<!DOCTYPE html>
<html>
<head>
<!-- Cabecera del documento HTML -->
</head>
<body>
<p>Esto es un parrafo de ejemplo</p>
<button>Esto es un boton</button>
<table>
<tr>
<th>Cabecera 1</th>
<th>Cabecera 2</th>
</tr>
<tr>
<td>Celda 1, 1</td>
<td>Celda 1, 2</td>
</tr>
<tr>
<td>Celda 2, 1</td>
<td>Celda 2, 2</td>
</tr>
</table>
</body>
</html>
133. HTML:
Atributos
• Sirven
para
configurar
los
elementos
• Tipos:
• Generales:
id,
style,
class,
name,
...
• Propios:
href,
value,
src,
...
• Personales:
data-*
• Cada
elemento
puede
tener
varios
<a href=”/target.html” class=”link” id=”firstlink”>Go to target</a>
<input type=”text” placeholder=”Write here...” disabled/>
<button data-custom=”custom data”>Click here</button>
134. CSS
• CSS
es
la
herramienta
estándar
para
definir
los
esWlos
visuales
del
contenido
de
una
página
web
• Un
esWlo
está
compuesto
de
una
o
varias
declaraciones
separadas
por
;
• Cada
declaración
consiste
en
una
propiedad
CSS
y
un
valor.
background-color: grey; color: white
135. CSS:
Propiedades
Propiedad Descripción Propiedad Descripción
background-color
Color
de
fondo
de
un
elemento border
El
borde
que
rodea
un
elemento
color
Color
principal
de
un
elemento
font-size
Tamaño
de
fuente
de
un
elemento
de
texto
height Altura
de
un
elemento padding
Espacio
entre
el
borde
de
un
elemento
y
su
contenido
text-decoration
Decoración
de
un
elemento
de
texto
width Ancho
de
un
elemento
137. CSS:
EsWlos
en
cascada
• Orden
de
prioridad
de
los
esWlos
• EsWlos
definidos
en
el
propio
elemento
• EsWlos
definidos
en
<style></style>
en
el
<head>
del
documento
• Archivos
CSS
enlazados
• EsWlos
por
defecto
del
navegador
<!DOCTYPE html>
<html>
<head>
<link rel=”stylesheet” type=”text/css” href=”styles.css” />
<style>
p {
color: red;
}
</style>
</head>
<body>
<p style=”color: blue”>The paragraph</p>
</body>
</html>
138. CSS:
Selectores
• Sintaxis
que
permite
seleccionar
elementos
de
un
documento
HTML
• Selectores
básicos
• #an_id:
El
elemento
cuyo
atributo
id
sea
“an_id”
• .a_class:
Los
elementos
cuyo
atributo
class
contenga
“a_class”
• p:
Elementos
de
Wpo
p
(párrafos)
• p[lang=”fr”]:
Párrafos
cuyo
atributo
lang
sea
igual
a
“fr”
• *[name=”x”]:
Cualquier
elemento
cuyo
atributo
name
sea
“x”
<style>
p {
color: red;
}
.attention {
color: red;
border: 2px solid red;
}
</style>
139. CSS:
Selectores
• Combinando
selectores
básicos
• span.fatal:
Elementos
<span>
cuyo
atributo
class
contenga
“fatal”
• span[lang=”fr”].warning:
<span>
con
atributo
lang=”fr”
y
además
class
“warning”
• Especificando
su
ubicación
en
el
documento
• #log
span:
Elementos
<span>
descendientes
del
elemento
con
id
“log”
• #log>span:
Elementos
<span>
que
sean
hijos
del
elemento
con
id
“log”
• body>h1:first-‐child:
El
primer
elemento
<h1>
que
sea
hijo
del
<body>
• Combinando
varios
selectores
• div,
#log:
Todos
los
elementos
<div>
y
el
elemento
con
id
“log”
141. El
navegador
como
sistema
operaWvo
• Los
navegadores
en
los
úlWmos
años
han
evolucionado
hasta
converWrse
en
sistemas
operaWvos
SO
Tradicional Navegador
Organizar
archivos
en
carpetas
representados
por
iconos
Organizar
bookmarks
en
carpetas
representados
por
iconos
Ejecutar
múlWples
aplicaciones
en
ventanas
disWntas
Visualizar
múlWples
páginas
o
en
diferentes
pestañas
API’s
de
acceso
a
red,
dibujar
gráficos
y
guardar
archivos
API’s
de
acceso
a
red,
dibujar
gráficos
y
guardar
datos
locales.
142. Javascript
en
...
• ...
páginas
web:
Mediante
JS
podemos
modificar
el
contenido,
aspecto
visual
y
el
comportamiento
de
los
componentes.
Es
el
conocido
DHTML.
• ...
aplicaciones
web:
Usan
el
API
de
acceso
a
red
(XMLHTTPRequest)
para
obtener
datos
dinámicamente
sin
recargar
la
página
y
usan
las
nuevas
capacidades
de
HTML.
Es
la
web
2.0
Su
uso
debe
ser
opcional
Su
uso
es
obligatorio
143. Incluyendo
Javascript
en
HTML
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<meta charset="utf8" />
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script>
var clicks = 0;
</script>
</head>
<body>
<input type="button" value="Click++"
onclick="clicks += 1; console.log('clicks: ' + clicks);" />
<a href="javascript:document.write('You have clicked: ' + clicks + ' times');" /> Show </a>
<a href="javascript:void(0)"
onclick="console.log('You have clicked: ' + clicks + ' times');" /> Show in console </a>
</body>
</html>
144. Ejecución
de
programas
JS
• Fase
síncrona:
Se
ejecuta
todo
el
código
definido
en
eWquetas
<script>
en
el
orden
en
que
aparece
escrito
en
el
documento
HTML.
• Fase
asíncrona
(event-‐driven):
Se
ejecutan
los
manejadores
de
eventos
definidos
en
el
código
HTML
cuando
ocurren
los
eventos.
145. Ejecución
de
programas
JS
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<meta charset="utf8" />
<script src="http://code.jquery.com/jquery-1.6.4.min.js"></script>
<script>
var clicks = 0;
</script>
</head>
<body>
<input type="button" value="Click++"
onclick="clicks += 1; console.log('clicks: ' + clicks);" />
<a href="javascript:document.write('You have clicked: ' + clicks + ' times');" /> Show </a>
<a href="javascript:void(0)"
onclick="console.log('You have clicked: ' + clicks + ' times');" /> Show in console </a>
</body>
</html>
146. El
objeto
window
• Es
el
objeto
global.
• Define
funciones
y
variables
globales.
• setTimeout()
y
setInterval()
• locaWon
• history
• navigator
• screen
• alert(),
confirm(),
prompt()
• más
en
la
documentación
147. DOM
• Estructura
• Nodos
• Atributos
• Recorriendo
el
DOM
• Modificando
el
DOM
148. DOM:
Estructura
• Representa
el
contenido
de
un
documento
HTML
como
un
árbol
de
nodos.
<!DOCTYPE html>
<html>
<head>
<title>Sample Document</title>
</head>
<body>
<h1>An HTML Document</h1>
<p>This is a <i>simple</i> document.
</body>
</html>
152. NodeList.
El
array
viviente
• Todos
los
métodos
de
selección,
excepto
getElementByid
y
querySelector
devuelven
un
objeto
NodeList.
• NodeList
es
un
Wpo
de
array
que
conWene
los
nodos.
• NodeList
es
un
array
viviente.
Siempre
está
actualizado,
excepto
si
es
resultado
de
selección
basada
en
selectores
CSS.
153. NodeList.
El
array
viviente
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
<meta charset="utf8" />
<script>
var p = document.getElementsByTagName(‘p’);
console.log(p.length); // 0
function loaded() {
console.log(p.length); // 1
}
</script>
</head>
<body onload=”loaded()”>
<p>Parrafo de prueba</p>
</body>
</html>
• Probando
el
array
viviente.
154. Recorriendo
el
DOM
• A
parWr
de
un
Node:
• parentNode
• childNodes
• firstChild,
lastChild
• nextSibling,
previousSibling
parentNode
NodepreviousSibling nextSibling
firstChild lastChild
childNodes
155. Información
de
los
Nodos
• Información
de
su
Wpo
y
contenido:
• nodeType:
Indica
el
Wpo
de
Nodo
• Document:
9,
Element:
1,
Text:
3,
Comments:
8
• nodeValue:
Contenido
textual
de
un
nodo
de
texto
o
comentario
• nodeName:
El
tag
name
• API
muy
sensible
a
las
modificaciones
del
documento.
Una
nueva
línea
en
blanco
se
interpretará
como
un
nodo
de
Wpo
texto
con
el
contenido
‘n’.
156. Considerando
solo
elementos
• Propiedades
exclusivas
de
nodos
de
Wpo
elemento
• children
• firstElementChild, lastElementChild
• nextElementSibling, previousElementSibling
• childElementCount
parentNode
NodepreviousElementSibling nextElementSibling
firstElementChild
children
lastElementChild
childElementCount:
2
157. DOM:
Ejercicio!
• Añadir
un
método
next
a
la
clase
Element
que
nos
de
el
siguiente
nodo
Element
hermano
garanWzando
que
funcione
incluso
en
navegadores
que
no
hayan
adoptado
el
API
basado
el
Elements
de
IE.
• Recordad
que
el
nodeType
de
los
nodos
de
Wpo
Element
es
1
• Documentación:
h2ps://developer.mozilla.org/en-‐US/docs/DOM/Node
158. DOM:
Ejercicio!
• Añadir
un
método
next
a
la
clase
Element
que
nos
de
el
siguiente
nodo
Element
hermano
garanWzando
que
funcione
incluso
en
navegadores
que
no
hayan
adoptado
el
API
basado
el
Elements
de
IE.
• Recordad
que
el
nodeType
de
los
nodos
de
Wpo
Element
es
1
• Documentación:
h2ps://developer.mozilla.org/en-‐US/docs/DOM/Node
Element.prototype.next = function() {
if (this.nextElementSibling) {
return this.nextElementSibling;
} else {
var sib = this.nextSibling;
while (sib && sib.nodeType !== 1) {
sib = sib.nextSibling;
}
return sib;
}
}
159. DOM:
Manejando
atributos
<script>
var p = document.getElementById(‘first’);
p.id === ‘first’; // true
p.className = ‘cssClass’;
p.removeAttribute(“class”);
var label = document.getElementsByTagName(‘label’)[0];
label.htmlFor; // “f_el”
</script>
...
<body>
<p id=”first”>Parrafo de prueba</p>
<label for=”f_el”>Label</label>
</body>
• Los
atributos
de
los
elementos
son
propiedades
del
objeto
Node
160. HTML5
dataset
<script>
var p = document.getElementById(‘first’);
p.dataset.x; // “1”
</script>
...
<body>
<p id=”first” data-x=”1” data-y=”2”>Parrafo de prueba</p>
</body>
• HTML5
permite
añadir
atributos
no
estándares
sin
generar
HTML
no
válido.
161. Atributos
como
objetos
<script>
var p = document.getElementById(‘first’);
p.attributes; // NodeList de objetos Attr
p.attributes[0];
p.attributes.id;
p.attributes[“id”];
p.attributes[“id”].value;
</script>
...
<body>
<p id=”first” data-x=”1” data-y=”2”>Parrafo de prueba</p>
</body>
• A2r:
Objeto
que
representa
un
atributo
HTML.
• Tienen
dos
propiedades:
name
y
value
162. Manejando
el
contenido
<script>
var p = document.getElementById(‘first’);
p.innerHTML; // “Parrafo de prueba”
p.innerHTML = “Parrafo modificado”;
</script>
...
<body>
<p id=”first”>Parrafo de prueba</p>
</body>
• innerHTML:
ObWene
o
asigna
el
contenido
p.outerHTML; // <p id=”first”>Parrafo de prueba</p>
p.outerHTML = “<label>A Label</label>;
• outerHTML:
ObWene
o
susWtuye
el
elemento
163. Manejando
el
contenido
• insertAdjacentHTML(posición,
contenido)
• posicion:
‘beforebegin’,
‘a‰erbegin’,
‘beforeend’,
‘a‰erend’
• contenido:
Cadena
HTML
a
insertar
165. Manejando
el
contenido
• Eliminando
y
reemplazando
nodos
• element.removeChild(nodo)
• element.replaceChild(nodo_nuevo,
nodo)
var new_p = document.createElement(“p”);
new_p.innerHTML = “Nuevo parrafo!”;
document.body.appendChlid(new_p);
var new_p2 = document.createElement(“p”);
new_p2.innerHTML = “Otro parrafo”;
document.body.insertBefore(new_p2, new_p);
document.body.removeChild(new_p2);
var replace = document.createElement(‘p’);
replace.innerHTML = “Reemplazo”;
document.body.replaceChild(replace, new_p);
<body>
...
<p>Reemplazo</p>
</body>
166. Manejando
el
contenido
• DocumentFragment
• Nodo
especial
que
sirve
como
contenedor
de
nodos.
• Nos
permite
trabajar
con
un
grupo
de
nodos
como
si
fuera
solo
uno.
var df = document.createDocumentFragment();
[‘a’, ‘e’, ‘i’, ‘o’. ‘u’].forEach(function(letter) {
var p = document.createElement(‘p’);
p.innerHTML = letter;
df.appendChild(p);
});
document.body.appendChild(df);
<body>
...
<p>a</p>
<p>e</p>
<p>i</p>
<p>o</p>
<p>u</p>
</body>
168. HTML:
Enlaces
al
documento
• Los
elementos
enlace
<a>
pueden
referenciar
secciones
dentro
del
documento.
• Al
hacer
click
en
el
enlace,
el
navegador
irá
a
la
sección
referenciada.
<a href=”#section1”>Go to section 1</a>
...
<h1 id=”section1”>
169. DOM:
Ejercicio!
• Mejorar
el
código
de
toc.js
para
que
cada
entrada
de
la
tabla
generada
sea
un
enlace
a
la
sección
correspondiente.
• No
se
puede
modificar
el
archivo
base.html,
por
tanto
el
algoritmo
deberá
modificar
también
el
contenido
existente
para
añadir
los
elementos
necesarios
para
que
los
enlaces
funcionen
correctamente.
• Para
que
cada
enlace
se
coloque
en
una
nueva
línea,
incluirlos
en
párrafos.
<p><a href=’#id_x’>Seccion 1.1</a></p>
<p><a href=’#id_y’>Seccion 1.2</a></p>
...
<h2 id=‘id_x’>Seccion 1.1</h2>
<h2 id=‘id_y’>Seccion 1.2</h2>
170. DOM:
Solucion!
function buildTOC() {
var toc = document.createElement('div');
document.body.insertBefore(toc, document.body.firstElementChild);
var headings = document.querySelectorAll("h1, h2, h3, h4, h5, h6");
for (var i = 0 ; i < headings.length ; ++i) {
var heading = headings[i];
heading.id = i;
var level = parseInt(heading.tagName.charAt(1));
var tocEntry = document.createElement('p');
var indentation = "";
for (var j = 0 ; j < level ; ++j) {
indentation += "+";
}
var link = document.createElement('a');
link.innerHTML = indentation + heading.innerHTML;
link.href = '#' + i;
tocEntry.appendChild(link);
toc.appendChild(tocEntry);
}
}
173. Geometría
de
los
elementos
• En
algunos
casos
vamos
a
necesitar
conocer
la
posición
y
tamaño
exactos
de
los
elementos.
• Sistema
de
coordenadas
cartesianas
con
el
origen
en
la
esquina
superior
izquierda
del
navegador.
• Pero
existen
dos
sistemas
de
coordenadas
dependiendo
del
scroll:
viewport
y
document.
x
x
y
y
Document
coordinates
Viewport
coordinates
Documento
HTML
Área
visible
del
documento
en
el
navegador
174. Geometría
de
los
elementos
window.pageXOffset
window.pageYOffset
Documento
HTML
Área
visible
del
documento
en
el
navegador
x
y
width
height
e.getBoundingClientRect()
var e = document.getElement...
var box = e.getBoundingClientRect();
e.x;
e.y;
e.width;
e.height;
175. Geometría
de
los
elementos
• Cuando
necesitamos
saber
qué
elemento
se
encuentra
en
una
posición
usaremos
document.elementFromPoint(x,
y);
uWlizando
coordenadas
viewport.
• Si
especificamos
coordenadas
fuera
del
viewport,
aunque
sean
coordenadas
válidas
del
document,
el
método
retornará
null
177. Eventos:
Conceptos
• Event
handler
o
event
listener:
Función
que
maneja
o
responde
a
un
determinado
evento.
• Event
object:
Objeto
asociado
al
evento
que
conWene
detalles
parWculares
del
mismo.
Se
suele
recibir
como
argumento
de
la
función
manejadora.
Tienen
propiedades:
• Tipo:
Cadena
que
indica
la
naturaleza
del
evento.
• Target:
Referencia
al
objeto
sobre
el
que
ocurrió
el
evento.
• Otras:
Dependen
de
cada
Wpo
de
evento,
coordenadas
de
ratón,
idenWficador
de
tecla
pulsada,
etc...
• Propagación
o
‘event
bubbling’:
Proceso
por
el
que
el
navegador
decid
cuál
es
el
objeto
que
debe
manejar
el
evento.
• Cancelación:
Técnica
por
la
que
podemos
capturar
un
evento
y
evitar
su
acción
por
defecto.
Muy
uWlizada
para
validar
campos
de
formularios.
178. Eventos:
Tipos
• Eventos
dependientes
del
disposiWvo:
Directamente
relacionados
con
las
capacidades
del
disposiWvo
(mousedown,
keydown,
touchmove,
...)
• Eventos
independientes
del
disposiWvo:
Eventos
de
entrada
que
no
dependen
de
las
capacidades
del
disposiWvo
(click,
texWnput,
...)
• Eventos
de
interfaz
de
usuario:
Eventos
de
alto
nivel,
generados
por
elementos
de
la
interfaz
(focus,
blur,
submit,
...)
• Eventos
de
cambio
de
estado:
Lanzados
por
acWvidad
en
la
red,
no
por
acWvidad
del
usuario
(load)
• Eventos
de
APIs:
Eventos
que
puedan
ser
lanzados
por
cualquier
API
que
estemos
usando
(playing
y
volumechange
de
elemento
<audio>)
• Timers
y
errores:
Eventos
que
se
lanzan
cuando
un
Wmer
completa
su
cuenta
o
cuando
ocurre
un
error
en
Wempo
de
ejecución.
179. Manejando
eventos
• Manejadores
como
propiedades
de
objetos
Nodo.
• Las
propiedades
que
representan
manejadores
comienzan
por
‘on’
seguido
del
nombre
del
evento,
por
ejemplo:
‘onclick’.
• Problema:
Sólo
permite
un
manejador
por
evento
y
objeto.
<script>
window.onload = function() {
var p = document.getElementById(‘myp’);
p.onclick = function() {
this.innerHTML = ‘Clicked‘;
};
};
</script>
...
<body>
<p id=”myp”>Click me!</p>
</body>
180. Manejando
eventos
• Manejadores
como
atributos
HTML.
• Comienzan
por
‘on’
seguido
del
nombre
del
evento.
• El
valor
es
una
cadena
de
código
Javascript.
• Cuando
se
usa
esta
técnica
hay
que
saber
que
es
el
body
quien
recibe
los
eventos
que
van
a
la
window,
por
ejemplo:
‘load’
<body>
<p id=”myp” onclick=”this.innerHTML = ‘Clicked‘;”>Click me!</p>
</body>
181. Manejando
eventos
• Manejadores
como
atributos
HTML.
• Es
una
técnica
no
recomendada
porque
genera
código
no
reusable
y
muy
diicil
de
mantener.
• Mezcla
la
lógica
de
presentación
(HTML)
con
la
lógica
del
programa
(JS)
• Solo
permite
un
manejador
por
evento
y
objeto
182. Manejando
eventos
• API
definiWvo
element.[add|remove]EventListener()
• Separación
adecuada
de
lógica
de
presentación
con
lógica
de
programa
• Permite
añadir
varios
manejadores
por
evento
y
objeto
• addEventListener(type,
listener,
useCapture)
<script>
window.addEventListener(‘load’, domLoaded, false);
function domLoaded() {
var p = document.getElementById(‘myp’);
p.addEventListener(‘click’, pClicked, false);
}
function pClicked() {
this.innerHTML = ‘Clicked‘;
}
</script>
...
<body>
<p id=”myp”>Click me!</p>
</body>
183. Manejando
eventos
• removeEventListener(type,
listener,
useCapture)
<script>
window.addEventListener(‘load’, domLoaded, false);
function domLoaded() {
var p = document.getElementById(‘myp’);
p.addEventListener(‘click’, pClicked, false);
}
function pClicked() {
this.innerHTML = ‘Clicked at: ‘ + new Date();
this.removeEventListener(‘click’, pClicked, false);
}
</script>
...
<body>
<p id=”myp”>Click me!</p>
</body>
184. Manejando
eventos:
Internet
Explorer
<
9
• element.[a2ach|detach]Event(type,
listener)
• No
soporta
captura
de
eventos
• El
primer
argumento
debe
ir
precedido
de
on:
onclick
<script>
window.attachEvent(‘onload’, domLoaded);
function domLoaded() {
var p = document.getElementById(‘myp’);
p.attachEvent(‘onclick’, pClicked);
function pClicked() {
p.innerHTML = ‘Clicked at: ‘ + new Date();
p.detachEvent(‘onclick’, pClicked);
}
}
</script>
...
<body>
<p id=”myp”>Click me!</p>
</body>
185. Manejando
eventos:
Internet
Explorer
<
9
• Código
cross-‐browser
<script>
if (window.addEventListener) {
window.addEventListener(‘onload’, domLoaded, false);
} else {
window.attachEvent(‘onload’, domLoaded);
}
function domLoaded() {
var p = document.getElementById(‘myp’);
if (p.addEventListener) {
p.addEventListener(‘onclick’, pClicked, false);
} else {
p.attachEvent(‘onclick’, pClicked);
}
function pClicked() {
p.innerHTML = ‘Clicked at: ‘ + new Date();
}
}
</script>
...
<body>
<p id=”myp”>Click me!</p>
</body>
186. Manejando
eventos:
Ejercicio!
• Crear
un
documento
HTML
que
contenga
un
botón
y
un
párrafo
que
indique
el
número
de
veces
que
se
ha
hecho
click
en
el
botón.
187. Manejando
eventos:
Ejercicio!
• Crear
un
documento
HTML
que
contenga
un
botón
y
un
párrafo
que
indique
el
número
de
veces
que
se
ha
hecho
click
en
el
botón.
<script>
function loaded() {
var clicks = 0;
var p = document.getElementsByTagName('p')[0];
var b = document.getElementsByTagName('button')[0];
b.addEventListener('click', clicked, false);
function clicked() {
clicks ++;
p.innerHTML = "Button was clicked: " + clicks + " times.";
}
}
</script>
...
<body onload="loaded();">
<button>Click</button>
<p>Button was never clicked</p>
</body>
188. Manejadores:
Argumentos
• Las
funciones
manejadoras
reciben
un
único
argumento,
que
es
el
objeto
evento
que
ha
ocurrido.
• Si
el
navegador
es
IE
<
9
los
manejadores
no
reciben
ningún
argumento,
el
objeto
evento
está
en
una
variable
global
event.
/*
* Manejador cross-browser
*/
<script>
function handler(event) {
event = event || window.event
....
}
</script>
...
189. Manejadores:
Contexto
• Los
manejadores
se
definen
como
métodos
del
objeto.
• El
contexto
(this)
dentro
del
manejador
es
el
propio
objeto
• En
IE
<
9,
que
los
manejadores
se
invocan
como
funciones
globales.
• El
contexto
dentro
del
manejador
es
el
objeto
global.
• Solución:
Usar
closure
<script>
...
function domLoaded() {
var p = document.getElementById(‘myp’);
p.attachEvent(‘onclick’, pClicked);
function pClicked() {
p.innerHTML = ‘Clicked at: ‘ + new Date();
}
}
</script>
191. Procesado
de
eventos
• 1ª
Fase:
Captura
de
eventos.
• 2ª
Fase:
Invocación
de
manejadores
en
el
objeto
que
lanzó
el
evento
• 3ª
Fase:
Propagación
(bubbling)
del
evento.
<html>
...
<body>
<div>
<a>
<img></img>
</a>
</div>
</body>
window
div
a
img
192. Fase
1:
Captura
de
eventos
• Se
acWva
con
el
tercer
parámetro
de
addEventListener(..,
..,
true).
Por
tanto,
no
disponible
en
IE
<
9.
• El
evento
recorre
el
árbol
en
senWdo
descendente
ejecutando
los
capturadores
registrados
si
existen.
• Esta
fase
nos
da
la
oportunidad
de
capturar
un
evento
antes
de
que
llegue
al
propio
objeto
que
lo
lanzó,
por
tanto
en
esta
fase
nunca
se
ejecutan
manejadores
del
target.
window
div
a
img
194. Fase
3:
Propagación
(bubbling)
• Se
recorre
el
árbol
en
senWdo
ascendente
ejecutando
todos
los
manejadores
registrados
para
el
evento.
window
div
a
img
195. Cancelación
...
• ...
de
la
acción
por
defecto.
• Manejadores
como
atributos
HTML
<a onclick=”return false;”>
Click here</a>
196. Cancelación
...
• ...
de
la
acción
por
defecto.
• Manejadores
como
atributos
HTML
<a onclick=”return false;”>
Click here</a>
• Manejadores
addEventListener
<script>
function handler(evt) {
...
evt.preventDefault();
}
</script>
197. Cancelación
...
• ...
de
la
acción
por
defecto.
• Manejadores
como
atributos
HTML
<a onclick=”return false;”>
Click here</a>
• Manejadores
addEventListener
<script>
function handler(evt) {
...
evt.preventDefault();
}
</script>
• Manejadores
a2achEvent
<script>
function handler() {
var evt = window.event;
evt.returnValue = false;
}
</script>
198. Cancelación
...
• ...
de
la
propagación.
• Manejadores
addEventListener
<script>
function handler(evt) {
...
evt.stopPropagation();
}
</script>
• Manejadores
a2achEvent
<script>
function handler() {
var evt = window.event;
evt.cancelBubble = true;
}
</script>
199. Cancelación
...
• ...
de
la
propagación.
• Manejadores
addEventListener
<script>
function handler(evt) {
...
evt.stopPropagation();
}
</script>
• Manejadores
a2achEvent
<script>
function handler() {
var evt = window.event;
evt.cancelBubble = true;
}
</script>
• ...
de
la
propagación
inmediatamente.
<script>
function handler(evt) {
...
evt.stopImmediatePropagation();
}
</script>
200. Manejo
de
eventos:
Ejercicio!
• Escribir
una
función
que
valide
los
datos
del
siguiente
formulario
y
no
permita
su
envío
a
menos
que
el
campo
obligatorio
esté
relleno.
...
<form>
<input type=”text” id=”mandatory” />
<input type=”submit” value=”Send!”/>
</form>
...
201. Manejo
de
eventos:
Solución!
• La
solución
pasa
por
cancelar
la
acción
por
defecto
del
click
en
el
input
submit.
<script>
function loaded() {
var submitbt = document.querySelector(‘input[type=”submit”]’);
submitbt.addEventListener(‘click’, checkForm, false);
}
function checkForm(evt) {
var mandatory = document.getElementById(‘mandatory’);
if (!mandatory.value) {
evt.preventDefault();
}
}
</script>
206. Aplicando
CSS
• Inline:
Mediante
el
atributo
HTML
style
<p style=”margin: 20px; border: solid red 2px”>
Parrafo con 20 px de margen y borde rojo</p>
207. Aplicando
CSS
• Inline:
Mediante
el
atributo
HTML
style
<p style=”margin: 20px; border: solid red 2px”>
Parrafo con 20 px de margen y borde rojo</p>
• En
la
sección
head:
Mediante
un
tag
<style>
<head>
...
<style>
p { // p es un selector CSS!!
margin: 20px;
border: solid red 2px;
}
</style>
...
</head>
208. Aplicando
CSS
• Hojas
de
esWlos
independientes
<head>
...
<link rel=”stylesheet” href=”css/styles.css” type=”text/css” />
...
</head>
/*
* css/styles.css
*/
p {
margin: 20px;
border: solid red 2px;
}
209. CSS:
EsWlos
en
cascada
• Orden
de
prioridad
de
los
esWlos
• EsWlos
definidos
en
el
propio
elemento
• EsWlos
definidos
en
<style></style>
en
el
<head>
del
documento
• Archivos
CSS
enlazados
• EsWlos
por
defecto
del
navegador
<!DOCTYPE html>
<html>
<head>
<link rel=”stylesheet” type=”text/css” href=”styles.css” />
<style>
p {
color: red;
}
</style>
</head>
<body>
<p style=”color: blue”>The paragraph</p>
</body>
</html>
210. CSS:
Selectores
• Sintaxis
que
permite
seleccionar
elementos
de
un
documento
HTML
• Selectores
básicos
• #an_id:
El
elemento
cuyo
atributo
id
sea
“an_id”
• .a_class:
Los
elementos
cuyo
atributo
class
contenga
“a_class”
• p:
Elementos
de
Wpo
p
(párrafos)
• p[lang=”fr”]:
Párrafos
cuyo
atributo
lang
sea
igual
a
“fr”
• *[name=”x”]:
Cualquier
elemento
cuyo
atributo
name
sea
“x”
<style>
p {
color: red;
}
.attention {
color: red;
border: 2px solid red;
}
</style>
211. CSS
para
programadores
• Propiedades
más
uWlizadas:
• position
• top, left, bottom, right
• width, height
• z-index
• display
• visibility
• clip
• overflow
• margin, padding
• border
• background
• opacity
216. Manipulando
esWlos
• Manipulando
la
lista
de
clases:
• classList
nos
devuelve
un
DOMTokenList
• add()
• remove()
• toggle()
• contains()
<script>
...
var clss = e.classList;
clss.add(“translucent”);
</script>
<body>
...
<p class=”translucent”> Parrafo </p>
</body>
217. CSS:
Ejercicio!
• Completar
la
función
loaded()
y
la
sección
style
para
obtener
este
resultado.
• No
añadir
nada
en
el
body,
todo
el
contenido
debe
ser
cargado
dinámicamente
con
JS.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>CSS Example</title>
<style>
img {
width: 200px;
height: 200px;
}
.translucent {
}
</style>
<script>
function loaded() {
}
</script>
</head>
<body onload="loaded();">
</body>
</html>
219. CSS:
El
esWlo
calculado
• Queremos
conocer
el
esWlo
de
un
elemento.
• window.getComputedStyle(element, null);
• Propiedades
read-‐only
• Valores
absolutos:
Todas
las
unidades
relaWvas,
como
porcentajes,
etc...
son
converWdas
a
pixeles.
• Todas
las
propiedades
de
acceso
rápido
son
converWdas
en
sus
correspondientes
fundamentales
<script>
function loaded() {
var p = document.getElementsByTagName(‘p’)[0];
var css = window.getComputedStyle(p, null);
console.log(css);
}
</script>
...
<body>
<p> Parrafo </p>
</body>
224. Javascript
y
HTTP
• AJAX:
Término
que
designa
aplicaciones
que
usan
JS
para
comunicarse
con
servidores
sin
recargar
la
página.
• Clase
XMLH2pRequest:
Representa
un
par
peWción-‐
respuesta.
• Request:
Verbo
HTTP,
URL,
Headers,
Body
• Response:
Status,
Headers,
Body
225. Enviando
una
peWción
• 1.-‐
Instanciación
• 2.-‐
Open
• 3.-‐
Headers
• 4.-‐
Body
y
envío
// 1
var req = new XMLHttpRequest();
// 2
req.open(“GET”, “path/to/my/service”);
// 3
req.setRequestHeader(“Content-Type”, “application/json”);
req.setRequestHeader(“Accept”, “application/json”);
// 4
req.send(null);
• Orden
de
configuración
obligatorio
226. Recibiendo
una
respuesta
• AJAX
es
un
API
asíncrono
Constante Valor Significado
UNSENT 0 No
se
ha
invocado
open
aún
OPENED 1 Se
ha
invocado
a
open
HEADERS_RECEIVED 2 Cabeceras
recibidas
LOADING 3
Se
está
recibiendo
la
respuesta
DONE 4 Respuesta
completa
227. Recibiendo
una
respuesta
// 1
var req = new XMLHttpRequest();
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status === 200) {
var type = request.getResponseHeader(“Content-Type”);
if (type.match(/^text/)) {
console.log(requ.responseText);
}
}
}
};
// 2
req.open(“GET”, “path/to/my/service”);
// 3
req.setRequestHeader(“Content-Type”, “application/json”);
req.setRequestHeader(“Accept”, “application/json”);
// 4
req.send(null);
228. AJAX:
Ejercicio!
• Escribir
un
documento
HTML
que
cargue
las
imágenes
retornadas
por
el
servicio
web.
• h2p://diplomado-‐test.herokuapp.com/le2ers
• Pista:
Bastará
con
asignar
la
propiedad
src
de
la
imagen
a
una
URL
para
que
el
navegador
la
cargue
automáWcamente.
229. AJAX:
Solución!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf8" />
<script>
function loaded() {
var req = new XMLHttpRequest();
req.open('GET', "http://diplomado-test.herokuapp.com/letters");
req.onreadystatechange = function(evt) {
if (this.readyState === 4 && this.status === 200) {
var json = JSON.parse(this.responseText);
var urls = json.forEach(function(item) {
var img = document.createElement("img");
img.style.width = img.style.height = "200px";
img.src = item.url;
document.body.appendChild(img);
});
}
};
req.send();
}
</script>
</head>
<body onload="loaded()">
</body>
</html>
230. XHR
2.0
• Define
un
nuevo
conjunto
de
eventos
para
controlar
el
estado
de
una
peWción
AJAX
• loadstart:
Cuando
send()
es
invocado
• progress:
Cada
50
ms
mientras
la
respuesta
está
siendo
descargada
• load:
La
peWción
ha
terminado
totalmente
• Errores:
• timeout,
abort,
error
232. Seguridad
• Primera
barrera
de
defensa:
Incapacidad.
• JS
no
Wene
acceso
al
sistema
de
ficheros
y
directorios
del
ordenador.
• JS
Wene
un
acceso
a
red
restringido
• Segunda
barrera
de
defensa:
Restricciones.
• JS
puede
abrir
nuevas
ventanas,
pero
para
prevenir
su
uso
abusivo
solo
podrá
abrirlas
en
respuesta
a
un
evento
del
usuario
• JS
puede
cerrar
ventanas,
pero
solamente
aquellas
que
ese
mismo
programa
ha
abierto.
Para
otras
necesita
confirmación
del
usuario.
• JS
no
puede
asignar
el
valor
de
un
HTML
FileUpload.
• Un
script
no
puede
leer
el
contenido
de
documentos
cargados
desde
otros
servidores,
ni
registrar
manejadores
de
eventos
de
estos
documentos.
Así
protege
de
leer
passwords,
etc...
Esto
se
conoce
como
‘Same-‐origin
policy’
233. Same-‐origin
policy
• Un
código
JS
sólo
puede
acceder
a
Windows
o
documents
que
Wenen
el
mismo
origen
que
el
documento
que
cargó
el
script.
• Origen
=
protocolo
+
host
+
puerto
del
documento
que
cargó
el
script
• Un
script
alojado
en
un
servidor
A
es
incluido
en
un
documento
de
un
servidor
B.
El
script
podrá
manejar
el
documento.
Si
el
script
abre
una
nueva
ventana
del
mismo
servidor
B,
también
podrá
manejarlo,
pero
si
abre
una
ventana
de
un
tercer
servidor
C,
entonces
Same-‐origin
policy
ya
no
le
permiWrá
manejarla.
• Esta
políWca
también
se
usa
para
determinar
con
qué
servidores
puede
comunicarse
con
AJAX