Fundamentos de POO en JS;
Mixins y otras técnicas de
reutilización
Maximiliano Fierro
@elmasse
Maximiliano Fierro
Solutions Architect
ECMAScript es un lenguaje
Orientado a Objetos
con herencia basada en delegación de prototipos
¿Qué significa?
Todo Objeto referencia a un
prototipo
¿Qué es un Objeto?
Un conjunto no ordenado de pares clave-valor.
Estos pares son llamados propiedades.
Cuando el valor de una propiedad es una función decimos
que es un método.
var obj = { msg : “hola”};
obj
msg “hola”
[[Prototype]] Object.prototype
…
[[Prototype]] null
[[Prototype]]
Propiedad interna que apunta al prototipo del
objeto. Algunas implementaciones proveen la
propiedad __proto__ (no-standard) como
referencia explícita.
obj.__proto__
> Object.prototype
Esto nos da acceso a las propiedades y métodos definidos en
Object.prototype:
obj.toString();
obj.hasOwnProperty();
etc..
Prototype Chain
Es el mecanismo de herencia en JavaScript.
Cuando le pedimos una propiedad a un objeto, se busca primero entre las
propiedades del objeto y luego si no existe, se sigue la cadena de
[[Prototype]] hasta encontrarlo.
Clases
Los objetos se crean mediante constructores.
Un constructor es una función que va a ser llamada con new.
El constructor tiene asociado un objeto llamado prototype.
El prototype se utiliza para definir propiedades de instancia.
Por defecto, el prototype es una instancia de Object, por lo tanto,
su [[Prototype]] apunta al Object.prototype.
constructor
Se utiliza para crear e inicializar un objeto.
// Constructor
function MyClass (msg) {
this.msg = msg;
};
// Instance method
MyClass.prototype.foo = function () {
console.log(this.msg);
};
var a = new MyClass(‘Hello!’);
a.foo(); // Hello!
MyClass.prototype
foo()
[[Prototype]
]
msg
a
[[Prototype]
]
[[Prototype]
]
Object.prototype
null
...
Herencia por Prototipos
La herencia se obtiene encadenando el prototype de
la clase con una instancia de la clase Padre.
// Constructor
function ClassA () {
// call parent constructor
MyClass.apply(this, arguments);
};
// inherit from MyClass
ClassA.prototype = Object.create(MyClass.prototype);
// Instance method
ClassA.prototype.bar = function () {
console.log(this.msg + ‘ from bar’);
};
var obj = new ClassA(‘Hello!’);
obj.foo(); // Hello!
obj.bar(); // Hello! from bar
MyClass.prototype
foo()
ClassA.prototype
bar()
[[Prototype]]
[[Prototype]]
msg
obj
Object.create
Object.create = function(Prototype) {
return { __proto__: Prototype };
};
Fácil, ¿no?
No tan rápido.
Hay algunos pequeños detalles que debemos tener
en cuenta, en especial al definir “propiedades”
El prototype es un objeto.
Accedemos al mismo prototype desde todas las
instancias de nuestra clase.
// Constructor
function MyClass () {
};
MyClass.prototype.array = [];
// Instance method
MyClass.prototype.foo = function () {
console.log(this.array);
};
var a = new MyClass();
var b = new MyClass();
a.foo(); // []
b.array.push(1);
b.array.push(2);
a.array.push(3);
a.foo(); // [1,2,3] ???
b.foo(); // [1,2,3] ???
a
[[Prototype]]
MyClass.prototype
foo fn()
array [1,2,3]
[[Prototype]] > Object
.protoype
b
[[Prototype]]
¿Entonces?
No definan propiedades en el prototype.
Usen el constructor. Después de todo, es el
encargado de inicializar el objeto.
// Constructor
function MyClass () {
this.array = [];
};
// Instance method
MyClass.prototype.foo = function () {
console.log(this.array);
};
var a = new MyClass();
var b = new MyClass();
a.foo(); // []
b.array.push(1);
b.array.push(2);
a.array.push(3);
a.foo(); // [3]
b.foo(); // [1,2]
a
array [3]
[[Prototype]] MyClass.prototype
foo fn()
[[Prototype]] > Object
.protoype
b
array [1,2]
[[Prototype]]
Reutilizando Código en
Programación Orientada a
Objetos
“Using inheritance as a vehicle to
reuse code is a bit like ordering a
happy meal because you want the
plastic toy”
Angus Croll.
*Abstract*Class / *Base*Class
Usualmente cuando utilizamos algún framework
que provee clases de las cuales tenemos que
extender (por ej. Views, Components,
Controllers, etc.) y nos encontramos código que
se repite entre las subclases.
Problemas
• Agregamos niveles de herencia.
• La clase Base/Abstracta se vuelve una
bolsa de funciones comunes.
• Las subclases acceden a mas funcionalidad
de la realmente requerida.
• Refactorizar se vuelve mas complejo.
Reutilizando Funciones
Toda función puede ser invocada con .call o
.apply (Borrowing)
“OK” en funciones simples...
var max = Math.max.apply(null, array);
… pero el código se vuelve verborrágico
var instance = {
msg: ‘Hello from instance’
};
//borrowing foo method from MyClass
MyClass.prototype.foo.apply(instance); // Hello from instance
//borrowing bar method from ClassA
ClassA.prototype.bar.apply(instance); // Hello from instance from bar
//borrowing foo method from ClassA inherited from MyClass
ClassA.prototype.foo.apply(instance); // Hello from instance
Mixins
Otra formas de reutilizar código
¿Qué es un Mixin?
Un Mixin es una clase que, por lo general, no
está pensada para ser instanciada o extendida,
sino combinada en otra clase.
El Mixin es combinado en la clase a través de
un merge.
En JavaScript, podemos usar Objects como
Mixins.
Mixins: Beneficios
Incentivan la reutilización de código.
Pueden ser utilizados como una
solución alternativa a la herencia
múltiple.
Evitan la ambigüedad de herencia (The
diamond problem) linealmente.
Implementación
Object.assign (o polyfill)
- El Mixin es combinado en el prototipo de
la Clase.
- Un Mixin puede ser una Clase o un Objeto.
function MixedClass () {
// call mixin constructor
MyClass.apply(this, arguments);
};
// apply Mixin
Object.assign(MixedClass.prototype,
MyClass.prototype);
// Instance method
MixedClass.prototype.bar = function () {
console.log(this.msg + ‘ from bar’);
};
var obj = new MixedClass(‘Hello!’);
obj.foo(); // Hello!
obj.bar(); // Hello! from bar
MixedClass.prototype
foo()
[[Prototype]
]
msg
obj
[[Prototype]
]
[[Prototype]
]
Object.prototype
null
...
bar()
EventEmitter como Mixin
function MyClass() {
// call Mixin constructor
EventEmitter.call(this, arguments);
}
Object.assign(MyClass.prototype, EventEmitter.prototype);
var obj = new MyClass();
obj.on(‘event’, function ( ) { console.log(‘event!’); });
obj.emit(‘event’);
Functional Mixins
El Mixin no es una clase sino una función que decora el
prototipo a través de “this”.
// Functional Mixin
function WithFoo() {
this.foo = function () {
console.log(this.msg);
}
return this;
}
// MixedClass definition
function MixedClass(msg) {
this.msg = msg;
}
// Apply Mixin
WithFoo.call(MixedClass.prototype);
MixedClass.prototype.bar = function () {
console.log(this.msg + ‘ from bar’);
};
var obj = new MixedClass(‘Hello!’);
obj.foo(); // Hello!
obj.bar(); // Hello! from bar
The Diamond Problem
BaseClass
ClassA ClassB
DerivedClass
foo()
var d = new DerivedClass();
d.foo() // ¿¿ cuál foo ??
...
...
...
foo()
The Diamond Problem
Object.assign(DerivedClass.prototype, ClassA.prototype, ClassB.prototype);
var d = new DerivedClass();
d.foo() // from ClassB
Object.assign(DerivedClass.prototype, ClassB.prototype, ClassA.prototype);
var d = new DerivedClass();
d.foo() // from ClassA
Llamar a un Método Sobre-escrito
….
Object.assign(DerivedClass.prototype, ClassA.prototype, ClassB.prototype);
DerivedClass.prototype.foo = function() {
// call “overridden” foo from A
ClassA.prototype.foo.apply(this, arguments);
}
Problemas
Métodos y propiedades son sobre-escritos
basados en la posición de la declaración.
Refactoring (agregar/renombrar métodos) puede
causar “problemas silenciosos”.
Llamar a un metodo sobre-escrito es
verborragico y propenso a errores.
Traits
Una especie de “Mixins Inteligentes”
¿Qué es un Trait?
Unidades de comportamiento que se
pueden componer.
Un tipo especial de clases sin estado.
Se los puede ver como clases incompletas.
Definen comportamiento y acceden al
estado a través de métodos requeridos.
Clase = Traits + Glue Code + State
(+ SuperClass)
Componiendo Comportamiento
Puede requerir un conjunto de métodos que
servirán como parámetros del comportamiento
ofrecido. (Clase incompleta)
Pueden ser compuestos por otros traits.
La colisión de nombres debe ser resuelta por el
desarrollador (usando alias y exclusiones)
Resolución de Conflictos
Un Conflicto aparece cuando combinamos dos o
mas traits que provean métodos llamados
idénticamente que no se originen en el mismo
trait.
Alias:Un método conflictivo se puede
“renombrar".
Exclusión: Podemos resolver el conflicto
excluyendo el método en cuestión.
MyList.prototype
+getCollection()
[[Prototype]
]
withFirst <Trait>
first()
*getCollection()
withLast <Trait>
last()
*getCollection()
withIterator <Trait>
iterator()
*getCollection()
@traits
[[Prototype]
]
collection:
[1,2,3,4,5]
list
var list = new MyList([1,2,3,4,5]);
console.log('collection: ', list.getCollection());
// [1,2,3,4,5]
console.log('first: ', list.first()); // 1
console.log('last: ', list.last()); // 5
console.log('iterate:');
var iterator = list.iterator();
var value;
while(value = iterator.next()){
console.log(value);
}
(*) Required Method
(+) Glue Code
MyList.prototype
getCollection()
[[Prototype]
]
first()
last()
iterator()
[[Prototype]
]
collection:
[1,2,3,4,5]
list
MyList.prototype
getCollection():
{Array}
[[Prototype]
]
withFirst <Trait>
first()
*getCollection()
withLast <Trait>
last()
*getCollection()
withIterator <Trait>
iterator()
*getCollection()
@traits
[[Prototype]
]
collection:
[1,2,3,4,5]
list
var list = new MyList([1,2,3,4,5]);
console.log('collection: ',
list.getCollection());
// [1,2,3,4,5]
console.log('first: ', list.first()); // 1
console.log('last: ', list.last()); // 5
console.log('iterate:');
var iterator = list.iterator();
var value;
while(value = iterator.next()){
console.log(value);
}
iterable <Trait>
MyList.prototype
getCollection():
{Array}
[[Prototype]
]
withFirst <Trait>
first()
*getCollection()
withLast <Trait>
last()
*getCollection()
withIterator <Trait>
iterator()
*getCollection()
@traits
[[Prototype]
]
collection:
[1,2,3,4,5]
list
ERROR! method “first” is defined twice!
iterable <Trait>
first()
Resolución de Conflictos:
Alias o Exclude
Podemos usar exclude en “first” del Trait iterable
o alias para renombrarlo en caso que queramos
usarlo (Una alternativa de llamar al metodo
sobre-escrito)
Implementaciones
Librerías:
• Traits.js
• CocktailJS
• (varias más en npm)
CocktailJS
npm install -s cocktail
cocktailjs.github.io
Annotations. Traits & Talents
Demo
Gracias!
@elmasse
github.com/elmasse

Más contenido relacionado

PPTX
03 Oop
PPT
Polimorfismo en Java
PDF
.NET UY Meetup 6 - Integrando con C/C++ por medio de P/Invoke by Juan Ramirez
PDF
Unidad 2 clases y objetos
PDF
ODP
Programación Orientada a Objetos para Python
03 Oop
Polimorfismo en Java
.NET UY Meetup 6 - Integrando con C/C++ por medio de P/Invoke by Juan Ramirez
Unidad 2 clases y objetos
Programación Orientada a Objetos para Python

La actualidad más candente (20)

PPT
Polimorfismo
PPT
Programación Orientada a Objetos
PDF
05. Creando e implementando objetos y métodos
PPT
Javascript continuación
ODP
02 python Programación orientada a objetos y funcional
PPT
PPT
2.android java
PPTX
4 Introducción al lenguaje Scala
PDF
Ruby para Java Developers
PPTX
Introducción a Scala
PDF
Polimorfismo
DOC
Java clases dictadas
PDF
Tema 4 clases_y_objetos
PDF
Polimorfismo
PPT
Constructor Y Destructor
PDF
Semana 6 Módulos Clases y Objetos
PDF
Javascript - 2014
PDF
Jyoc java-cap08 principios poo
PPTX
Constructores en java(grupo 8)
PPT
Net1 oop vbnet
Polimorfismo
Programación Orientada a Objetos
05. Creando e implementando objetos y métodos
Javascript continuación
02 python Programación orientada a objetos y funcional
2.android java
4 Introducción al lenguaje Scala
Ruby para Java Developers
Introducción a Scala
Polimorfismo
Java clases dictadas
Tema 4 clases_y_objetos
Polimorfismo
Constructor Y Destructor
Semana 6 Módulos Clases y Objetos
Javascript - 2014
Jyoc java-cap08 principios poo
Constructores en java(grupo 8)
Net1 oop vbnet
Publicidad

Similar a Fundamentos POO en JS. Mixins y Traits. (20)

ODP
Prototype-based, object-oriented programming
PDF
Javascript OOP
PDF
Curso de doctorado de Tecnología de Objetos: Sistemas Orientados a objetos y ...
PPTX
Programacion orientada a objetos en javascript
PDF
La propiedad prototype en la programación orientada a objetos con JavaScript
PPTX
programacion-orientada-a-objetos-poo_c4774196-cfdb-412e-bae5-210a97d78f8b.pptx
PPTX
programacion-orientada-a-objetos-poo_c4774196-cfdb-412e-bae5-210a97d78f8b.pptx
ODP
Prototype-based programming with PROWL.
DOCX
Analisis orientado a objetos
PPTX
OOP-JS pjs
PPTX
OOP.JAVAS pjs
PPT
programacion orientada a objetos
PPT
Object Oriented Javascript
PPTX
JavaScript1ckjdfiudafhadvjsadgdhsagcjhASBjhcSJHcSAc
PPTX
_Concepto de interfaz_interfaz_interfaz_interfaz_interfaz_.pptx
PDF
Clases y Objetos para programar introducción para programar
PPTX
JavaScript1IAxdxdxdxdxdxdxdxddddddd.pptx
DOCX
Analisis de la PPO
PPT
Poo
PPTX
Introduccion a la poo
Prototype-based, object-oriented programming
Javascript OOP
Curso de doctorado de Tecnología de Objetos: Sistemas Orientados a objetos y ...
Programacion orientada a objetos en javascript
La propiedad prototype en la programación orientada a objetos con JavaScript
programacion-orientada-a-objetos-poo_c4774196-cfdb-412e-bae5-210a97d78f8b.pptx
programacion-orientada-a-objetos-poo_c4774196-cfdb-412e-bae5-210a97d78f8b.pptx
Prototype-based programming with PROWL.
Analisis orientado a objetos
OOP-JS pjs
OOP.JAVAS pjs
programacion orientada a objetos
Object Oriented Javascript
JavaScript1ckjdfiudafhadvjsadgdhsagcjhASBjhcSJHcSAc
_Concepto de interfaz_interfaz_interfaz_interfaz_interfaz_.pptx
Clases y Objetos para programar introducción para programar
JavaScript1IAxdxdxdxdxdxdxdxddddddd.pptx
Analisis de la PPO
Poo
Introduccion a la poo
Publicidad

Último (9)

PPTX
hojas_de_calculo_aplicado para microsoft office
PPTX
PROPIEDADES Y METODOS DE PrOO CON PYTHON
PPTX
presentación de introducción a las metodologías agiles .pptx
PPTX
Control de seguridad en los sitios web.pptx
PDF
Clase 3 - Presentación visual (Insertando objetos visuales) POWER POINT.pdf
PDF
DNS_SERVIDORES PARA ASER PRACTICAS EN REDES
PDF
Presentacion de compiladores e interpretes
PPTX
Implementación equipo monitor12.08.25.pptx
PPTX
ORIGEN DE LA IA - GRADO 1102 INTELIGENCIA
hojas_de_calculo_aplicado para microsoft office
PROPIEDADES Y METODOS DE PrOO CON PYTHON
presentación de introducción a las metodologías agiles .pptx
Control de seguridad en los sitios web.pptx
Clase 3 - Presentación visual (Insertando objetos visuales) POWER POINT.pdf
DNS_SERVIDORES PARA ASER PRACTICAS EN REDES
Presentacion de compiladores e interpretes
Implementación equipo monitor12.08.25.pptx
ORIGEN DE LA IA - GRADO 1102 INTELIGENCIA

Fundamentos POO en JS. Mixins y Traits.

Notas del editor

  • #15: Objects are created via constructors. Constructor is a function that creates and initializes the newly created object.
  • #17: Prototypal Inheritance is achieved by chaining the prototype with a parent class object instance.
  • #28: Inheritance as a mechanism to reuse code
  • #31: call -> c for comma separated apply -> a for arguments
  • #37: The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object
  • #41: Names in Functional Mixins express behavior. Idea: Mixin should be a process.