Type.new()

NOTA: Este artículo está centrado en un tema que ya comenté en el post anterior, pero de una forma más organizada y centrada, algunos fragmentos están extraídos del post anterior para mayor claridad.

Constructores en Javascript

He hablado antes de la limitación de los constructores javascript y sobre todo de la complejidad de extenderlos

function Person(name) {
  this.name = name;
}
Person.prototype.methodA = function() { ... };

function Employee(name, position) {
  Person.call(this, name);
  this.position = position;
}
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.methodB = function() { ... };

Esto es un asunto que trae de cabeza a la mayoría de la gente que programa javascript, la dificiltad que conlleva crear una simple «clase» hasta el punto que en la siguiente versión del ECMAScript (el estándar en el que está basado Javascript) han incluído una forma más sencilla de hacer lo mismo: la palabra clave class

class Person {
  constructor(name) {
    this.name = name;
  }
  methodA() { }
}

class Employee extends Person {
  constructor(name, position) {
    super(name);
    this.position = position;
  }
  methodB() { }
}

Pruébame

Aunque he visto a mucha gente emocionada pensando que ECMAScript 6 traerá clases reales tengo que decir que este código no hace ni más ni menos que lo que hace el primer código. Y es muy importante saberlo porque aunque prezcan classes como las de Java o C++, en este caso siguen siendo objetos usando herencia por prototipos y esconderlo solo servirá para no saber porqué el código no funciona como esperamos.

En cualquier caso vemos que definir tipos en javascript es complicado y la solución propuesta por el equipo de ECMA no es, en mi opinión, la más adecuada.

 Orientado a objetos

Creo que el problema se aloja en la definición que dimos en un principio a «Programación Orientada a Objetos» (Object Oriented Programming, OOP) ya que los primeros lenguajes OOP creaban objetos usando clases y otras herramientas, y aunque los objetos son la base del sistema la estructura está dada por las clases. Lo que sería Programación Orientada a Objetos con Clases.

Después recibimos otros lenguajes que también se definian como «Programación Orientados a Objetos» pero enfocado de otra forma, entre ellos javascript. En este caso el lenguaje no tiene clases sino que todo son objetos y la estructura se crea mediante prototipos, todo objeto puede ser el prototipo de otro objeto y esto significa que si B prototipa a A todas las propiedades que A tenga también existirán en B. Esto es lo que llamo Programación Orientada a Objetos con Prototipos.

Me he cruzado con mucha gente que piensa que la Programación Orientada a Objetos no es posible sin clases y que si Javascript no tiene clases no puede denominarse orientado a objetos. Como en todo debate entre geeks acabamos en la wikipedia:

La programación orientada a objetos o POO (OOP según sus siglas en inglés) es un paradigma de programación que usa los objetos en sus interacciones, para diseñar aplicaciones y programas informáticos. Está basado en varias técnicas, incluyendo herencia, cohesión, abstracción, polimorfismo, acoplamiento y encapsulamiento.

En resumen, un lenguaje orientado a objetos es el que tiene objetos (brillante conclusión) y cumple una serie de técnicas (herencia, cohesión, abstracción, polimorfismo…) que en el caso de Java se hace mediante clases y en el caso de Javascript se hace mediante prototipos.

 Los inicios de Javascript

Javascript en sus inicios se llamó LiveScript, cuenta la leyenda que por aquella época Java estaba teniendo mucho éxito y por marketing se decidió llamar al nuevo lenguaje JavaScript. También cuenta que por el mismo motivo a última hora se decidió modificar el lenguaje para parecerse más a Java añadiendo, entre otras funcionalidades, el operador new para que pareciera tener clases.

Hay algo muy curioso en los constructores Javascript, que en el fondo son simples funciones, y es que todas las funciones javascript tienen la propiedad prototype que por defecto trae un objeto que solo tiene una propiedad, la propiedad constructor que es el propio constructor.

function Testing() { }
console.log(Testing.prototype.constructor === Testing);

var proto = Testing.prototype;
console.log(proto.constructor.prototype === proto);

 Constructores vs objetos prototipo

Esto me hace pensar que quizás la intención original de los objetos en javascript no era tener constructores que contienen prototipos sino tener prototipos que contienen constructores. Es decir: en lugar de…

function MyType() {
  this.id = 1;
}
MyType.prototype.methodA = function() { ... }

Hacer esto…

var MyType = {
  constructor: function() {
    this.id = 1;
  },
  methodA: function() { ... },
};

Vaya! No parece una forma mucho más sencilla de declarar tipos? [Aquí][5] podemos comparar el mismo tipo escrito con constructores y con este paradigma y juzguen ustedes mismos. Y que pasa cuando intentamos invocar al constructor? hay que usar .call() o .apply() para pasarle this?

var isntancia = Object.create(MyType);
instancia.constructor();

BOOM! Constructor ya recibe this porque es invocado directamente en la instancia! No es exageradamente sencillo y lógico desde éste punto de vista?

Además por accidente hemos quitado de en medio la función constructora y lo que tenemos es un simple objeto, el elemento más básico de la programación orientada a objetos. Es decir, para declarar un tipo solo tenemos que crear un objeto, para prototipar un objeto solo necesitamos un paso

var SubType = Object.create(MyType);

No estamos obligados, a diferenia del primer caso, a crear un nuevo constructor para crear un subtipo, por la herencia por prototipos tenemos el mismo constructor que MyType

console.log(SubType.constructor === MyType.constructor);
// true

Pruébame

Y la mejor parte, que pasa si queremos crear un tipo sin constructor? No hay problema.

var MyType = {};
console.log(MyType.constructor); // Object

Pruébame

ECMAScript 6

Este paradigma se parece bastante a la forma de crear clases en ECMAScript 6

class MyType {
  constructor() {
    this.id = 1;
  }
  methodA() { ... }
}

Que alguno dirá, si, pero con las clases de ECMAScript 6 podemos extender clases, llamar al método padre con super y nos ahorramos poner function… Pero esas no son funcionalidades de las clases de ECMAScript 6, esas son funcionalidades de todos los objetos en ECMAScript 6.

// Clase ECMAScript 6
class Employee extends Person {
  constructor(name, postition) {
    super(name);
    this.position = postition;
  }
  methodA() { ... }
}

// Objeto en ECMAScript 6 estándar
var Employee = {
  __proto__: Person,

  constructor() {
    super(name)
    this.id = 1;
  },
  methodA() { ... }
};

Las diferencias entre una clase ECMAScript 6 y un objeto en ECMAScript 6 son mínimas, pero mientras que una clase nos hace pensar que Employee se comportará como una clase Java cuando no es así, un objeto es simplemente eso, un objeto y todos somos capaces de entender como se comporta un objeto, no? (si no que haces leyendo esto? o.o)

Pero dejemos ECMAScript 6 de lado por ahora, que aún tiene que transcurrir tiempo antes de que podamos usarlo en serio.

Instanciación

Hasta aquí era la definicion del tipo, pero como creamos una instancia? Primero tendríamos que plantearnos que es una instancia, si no tenemos clases podemos tener instancias? Según la wikipedia

En el paradigma de la orientación a objetos, una instancia (en inglés, instance) se refiere a una realización específica de una clase o prototipo determinados.

Pero, al menos a mi, no importa mucho la palabra; el tema es que nosotros creamos objetos para que hagan de prototipos y queremos crear «instancias» de estos prototipos. La forma de prototipar un objeto es usando Object.create()

var instance = Object.create(MyType);

Pero, un momento… Esto es exactamente lo mismo que hicimos para crear un subtipo, no? Si. Entonces en que se diferencia una instancia de un subtipo? En general, nada. Una instancia ES un subtipo. Pero en la mayoría de los casos las «instancias» tienen una necesidad que los subtipos no tienen: en una instancia se invoca al constructor, en un subtipo no.

var MyType = {
  constructor: function() {
    this.id = 1;
  }
};

// Crear sub-tipo
var SubType = Object.create(MyType);

// Crear instancia
var instance = Object.create(MyType);
instance.constructor();

Esta similitud entre una instancia y un SubTipo nos ayuda a entender hasta que punto en el fondo Javascript es muy, muy sencillo: todo son objetos; no hay diferencia entre un tipo y una instancia porque la diferencia es conceptual.

Esto es muy útil para entender la sencillez y el corazón de Javascript, pero es un poco tedioso tener que hacer dos pasos para instanciar, podríamos simplificarlo?

Type.new() es el nuevo new

Lo cierto es que podríamos, podemos hacer una función que haga este proceso:

function createInstance(Type) {
  var instance = Object.create(Type);
  instance.constructor();
  return instance;
}

var Type = {
  constructor: function() {
    this.id = 1;
  }
};

var instance1 = createInstance(Type);

var TypeWithoutConstructor = {};
var instance2 = createInstance(TypeWithoutConstructor);

Pruébame

Y que pasa si en lugar de llamarla createInstance la llamamos $new por ejemplo?

var instance = $new(MyType);

Empieza a parecer similar, solo nos faltaría cambiar la funcion $new para pasarle parámetros al constructor

function $new(Type, params) {
  var instance = Object.create(Type);
  instance.constructor.apply(instance, params);
  return instance;
}

var Type = {
  constructor: function(name) {
    this.name = name;
  }
};

var instance = $new(Type, [ 'bob' ]);

Pruébame

Parece funcionar, pero solo para acabar de pulirlo, porqué no ponemos $new como método de Type? así podríamos pasarle los argumentos sin el array y como ECMAScript 5 nos permite usar palabras clave como propiedades de objeto podemos llamarlo simplemente new.

var Type = {
    new: function() {
        var instance = Object.create(this);
        instance.constructor.apply(instance, arguments);
        return instance;
    },
    constructor: function(name) {
        this.name = name;
    }
};

var instance = Type.new('bob' );

Pruébame

Y tenemos una forma que podemos usar con ECMAScript 5 para crear tipos e instancias de forma sencilla. Pero que diferencia hay entre esto y hacer un new? A parte de la ya mencionada simplicidad para crear y extender tipos, tiene más ventajas, principalmente porque nos permite controlar más exactamente cómo se crea un objeto que en algunos casos es conveniente cambiarlo (en la mayoría no), pero excede el alcance de éste post.

 Conclusión

Después de pasarme los últimos años probando mil y una formas de crear y extender «clases» para encontrar la forma más sencilla, rápida y elegante, muchas de ellas registradas en este blog; me quedo con ésta. La lección que me dio javascript es que no es conveniente luchar contra su naturaleza, si queremos usar javascript y no morir en el intento lo más razonable es usar javascript y no tratarlo en contra de su naturaleza.

Aún está por verse pero creo que este sistema incluso puede competir cara a cara con las «clases» de ECMAScript 6, pero en cualquier caso la conversión entre un tipo creado por constructor y uno creado con este sistema es muy sencilla

Por ejemplo, convertir un tipo creado con este sistema a constructor para usarlo con new:

var MyType = {
  myMethod: function() { ... },
};

function MyConstructor() {
  MyType.constructor.apply(this, arguments);
}
MyConstructor.prototype = MyType;

Pruébame

O convertir un constructor a este paradigma:

function MyConstructor() {
  this.value = 1;
}
MyConstructor.prototype.myMethod = function() { ... };

var MyType = MyConstructor.prototype;
// y si queres añadir new...
MyType.new = $new;

Pruébame

Inicializador

Para finalizar un bonus, después de toda esta travesía me he dado cuenta que el constructor, que para javascript parece tan importante, no lo es tanto. Si nos paramos a mirar el constructor vemos que es una simple función

function MyType() { ... }

No tiene nada de especial, incluso podemos invocarla como una función y no construye nada. Entonces quién construye? new. Es el operador new el que crea el nuevo objeto y luego invoca el método llamado «constructor», que no se diferencia en nada de cualquier otro método que podría tener el objeto.

Por como yo lo veo, la función del constructor es más inicializar que construir, debe encargarse de inicializar las propiedades del objeto, no construir. Visto así es evidente que el nombre «constructor» no es apropiado, en mi caso prefiero la denominación «initializer» o simplemente «init», como Backbone ya hace en sus objetos.

Por eso en mis proyectos cuando utilizo este paradigma, prefiero que mi función $new invoque el método init en lugar de llamar al método constructor.

function $new() {
  var obj = Object.create(this);
  obj.init.apply(obj, arguments);
  return obj;
}

var MyType = {
  new: $new,
  init: function() {
    this.value = 1;
  }
};

var instance = MyType.new();

Pruébame

2.148 thoughts on “Type.new()

  1. When I originally commented I clicked the «Notify me when new comments are added» checkbox and now each time a comment is added I get four emails with the same comment. Is there any way you can remove me from that service? Thank you!

  2. Hi there terrific website! Does running a blog similar to this take a lot of work? I have virtually no understanding of coding however I had been hoping to start my own blog in the near future. Anyway, should you have any ideas or tips for new blog owners please share. I know this is off subject however I simply wanted to ask. Kudos!

  3. Hi there! I just wanted to ask if you ever have any issues with hackers? My last blog (wordpress) was hacked and I ended up losing several weeks of hard work due to no backup. Do you have any methods to stop hackers?

  4. The other day, while I was at work, my sister stole my iPad and tested to see if it can survive a 40 foot drop, just so she can be a youtube sensation. My apple ipad is now broken and she has 83 views. I know this is totally off topic but I had to share it with someone!

  5. Hi there would you mind letting me know which web host you’re utilizing? I’ve loaded your blog in 3 different web browsers and I must say this blog loads a lot faster then most. Can you suggest a good hosting provider at a honest price? Thanks a lot, I appreciate it!

  6. Hey there! I understand this is kind of off-topic however I needed to ask. Does running a well-established website such as yours take a lot of work? I am brand new to running a blog but I do write in my diary everyday. I’d like to start a blog so I can share my personal experience and thoughts online. Please let me know if you have any kind of ideas or tips for brand new aspiring blog owners. Appreciate it!

  7. I know this if off topic but I’m looking into starting my own weblog and was curious what all is required to get setup? I’m assuming having a blog like yours would cost a pretty penny? I’m not very internet smart so I’m not 100% certain. Any tips or advice would be greatly appreciated. Many thanks

  8. Have you ever considered publishing an e-book or guest authoring on other blogs? I have a blog based on the same topics you discuss and would love to have you share some stories/information. I know my audience would value your work. If you are even remotely interested, feel free to send me an e mail.

  9. Awesome blog! Do you have any suggestions for aspiring writers? I’m hoping to start my own website soon but I’m a little lost on everything. Would you suggest starting with a free platform like WordPress or go for a paid option? There are so many choices out there that I’m totally confused .. Any recommendations? Bless you!

  10. My spouse and I absolutely love your blog and find almost all of your post’s to be
    just what I’m looking for. Would you offer guest writers to
    write content in your case? I wouldn’t mind producing
    a post or elaborating on some of the subjects you write about here.
    Again, awesome website!

  11. Hi there, I discovered your website by means of Google at the same time as looking for a related topic, your site got here up, it appears to be like good. I have bookmarked it in my google bookmarks.

  12. I intended to put you a tiny word in order to thank you as before for the wonderful information you’ve discussed in this article. It’s particularly open-handed of people like you to offer freely what a number of us would have marketed as an e book to get some cash on their own, particularly now that you could possibly have tried it if you considered necessary. The things additionally worked like a good way to fully grasp other individuals have similar fervor just like my own to realize many more on the subject of this condition. I think there are many more pleasant moments ahead for people who look over your website.

  13. My programmer is trying to persuade me to move to .net from PHP. I have always disliked the idea because of the expenses. But he’s tryiong none the less. I’ve been using Movable-type on several websites for about a year and am concerned about switching to another platform. I have heard great things about blogengine.net. Is there a way I can import all my wordpress content into it? Any kind of help would be greatly appreciated!

  14. Great blog! Do you have any helpful hints for aspiring writers? I’m planning to start my own website soon but I’m a little lost on everything. Would you propose starting with a free platform like WordPress or go for a paid option? There are so many options out there that I’m totally confused .. Any tips? Kudos!

  15. I really like your blog.. very nice colors & theme. Did you create this website yourself or did you hire someone to do it for you? Plz answer back as I’m looking to design my own blog and would like to know where u got this from. thank you

  16. Great blog! Is your theme custom made or did you download it from somewhere? A design like yours with a few simple tweeks would really make my blog stand out. Please let me know where you got your theme. Cheers

  17. Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.

  18. Greetings from Colorado! I’m bored at work so I decided to check out your site on my iphone during lunch break. I really like the info you provide here and can’t wait to take a look when I get home. I’m surprised at how quick your blog loaded on my mobile .. I’m not even using WIFI, just 3G .. Anyhow, good site!

  19. With havin so much content do you ever run into any problems of plagorism or copyright infringement? My site has a lot of completely unique content I’ve either authored myself or outsourced but it looks like a lot of it is popping it up all over the internet without my authorization. Do you know any techniques to help prevent content from being ripped off? I’d definitely appreciate it.

  20. Hi there great blog! Does running a blog like this take a great deal of work? I have virtually no knowledge of computer programming but I had been hoping to start my own blog soon. Anyways, should you have any suggestions or techniques for new blog owners please share. I understand this is off subject however I just had to ask. Kudos!

  21. I really like your blog.. very nice colors & theme. Did you design this website yourself or did you hire someone to do it for you? Plz answer back as I’m looking to construct my own blog and would like to know where u got this from. thank you

  22. Does your site have a contact page? I’m having a tough time locating it but, I’d like to send you an email. I’ve got some creative ideas for your blog you might be interested in hearing. Either way, great site and I look forward to seeing it grow over time.

  23. It’s a shame you don’t have a donate button! I’d certainly donate to this superb blog! I suppose for now i’ll settle for bookmarking and adding your RSS feed to my Google account. I look forward to brand new updates and will talk about this site with my Facebook group. Chat soon!

  24. Hey there would you mind sharing which blog platform you’re using? I’m looking to start my own blog in the near future but I’m having a difficult time deciding between BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your design seems different then most blogs and I’m looking for something unique. P.S Sorry for being off-topic but I had to ask!

  25. My partner and I stumbled over here from a different page and thought I might as well check things out. I like what I see so i am just following you. Look forward to looking into your web page repeatedly.

  26. Hey excellent blog! Does running a blog such as this take a lot of work? I’ve absolutely no expertise in coding however I had been hoping to start my own blog soon. Anyhow, should you have any suggestions or tips for new blog owners please share. I know this is off subject nevertheless I just had to ask. Appreciate it!

  27. Write more, thats all I have to say. Literally, it seems as though you relied on the video to make your point. You definitely know what youre talking about, why waste your intelligence on just posting videos to your blog when you could be giving us something enlightening to read?

  28. My partner and I stumbled over here from a different page and thought I may as well check things out. I like what I see so now i’m following you. Look forward to looking over your web page yet again.

  29. Hey! I understand this is sort of off-topic however I needed to ask. Does managing a well-established blog like yours require a lot of work? I’m brand new to writing a blog however I do write in my diary daily. I’d like to start a blog so I can easily share my personal experience and views online. Please let me know if you have any suggestions or tips for new aspiring blog owners. Appreciate it!

  30. Good day! This is kind of off topic but I need some guidance from an established blog. Is it hard to set up your own blog? I’m not very techincal but I can figure things out pretty fast. I’m thinking about creating my own but I’m not sure where to begin. Do you have any ideas or suggestions? Thanks

  31. Do you have a spam issue on this site; I also am a blogger, and I was wondering your situation; many of us have created some nice methods and we are looking to trade methods with other folks, please shoot me an email if interested.

  32. Do you mind if I quote a couple of your posts as long as I provide credit and sources back to your blog? My blog site is in the exact same area of interest as yours and my users would certainly benefit from a lot of the information you provide here. Please let me know if this ok with you. Thanks a lot!

  33. Hey this is kind of of off topic but I was wanting to know if blogs use WYSIWYG editors or if you have to manually code with HTML. I’m starting a blog soon but have no coding knowledge so I wanted to get guidance from someone with experience. Any help would be greatly appreciated!

  34. With havin so much content do you ever run into any problems of plagorism or copyright violation? My blog has a lot of completely unique content I’ve either written myself or outsourced but it seems a lot of it is popping it up all over the web without my authorization. Do you know any ways to help stop content from being ripped off? I’d truly appreciate it.

  35. Hey I know this is off topic but I was wondering if you knew of any widgets I could add to my blog that automatically tweet my newest twitter updates. I’ve been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.

  36. Howdy! This is my 1st comment here so I just wanted to give a quick shout out and say I truly enjoy reading your blog posts. Can you recommend any other blogs/websites/forums that deal with the same topics? Thanks!

  37. Admiring the persistence you put into your site and detailed information you offer. It’s awesome to come across a blog every once in a while that isn’t the same unwanted rehashed information. Fantastic read! I’ve saved your site and I’m including your RSS feeds to my Google account.

  38. Hey there I am so grateful I found your blog, I really found you by accident, while I was looking on Bing for something else, Anyhow I am here now and would just like to say kudos for a remarkable post and a all round exciting blog (I also love the theme/design), I don’t have time to go through it all at the moment but I have saved it and also included your RSS feeds, so when I have time I will be back to read a lot more, Please do keep up the great work.

  39. First of all I would like to say wonderful blog! I had a quick question in which I’d like to ask if you do not mind. I was interested to find out how you center yourself and clear your thoughts prior to writing. I have had difficulty clearing my mind in getting my thoughts out there. I do take pleasure in writing however it just seems like the first 10 to 15 minutes are wasted just trying to figure out how to begin. Any ideas or tips? Thank you!

  40. I’m truly enjoying the design and layout of your blog. It’s a very easy on the eyes which makes it much more pleasant for me to come here and visit more often. Did you hire out a developer to create your theme? Outstanding work!

  41. Its such as you learn my thoughts! You seem to know so much approximately
    this, like you wrote the e-book in it or something.
    I believe that you just could do with some percent to drive the message house a little bit, but other than that, this is great blog.

    A great read. I’ll definitely be back. Phone Sex