ECMAScript 5 _.extend

A algunos ya os he comentado los problemas que NC Zakas comenta con el _.extend de underscore y los getters:

var a = {
  init: function() {
    this.list = [];
  },

  get first() {
    return this.list[0];
  }
};

O

var a = {
  init: function() {
    this.list = [];
  }
};

Object.defineProperty(a, 'first', {
  get: function() {
    return this.list[0];
  }
});

Y que si hacemos _.extend(a) va a fallar porque intentará hacer result.first = a.first ejecutando el getter. Pero como aún no hemos llamado al .init() en a porque solo es un prototipo, la propiedad .list es undefined produciendo un error.

Pues bien, yo creía que esto se solucionaba extrayendo el descriptor de la propiedad y usando ese mismo descriptor para copiar la propiedad al nuevo objeto:

function extend(obj) {
  var result = {};
  var properties = Object.keys(obj);

  properties.forEach(function(prop) {
    var descriptor = Object.getOwnPropertyDescriptor(obj, prop);
    Object.defineProperty(result, prop, descriptor);
  });

  return result;
}

Pero he usado esto en la librería de promises y me he dado cuenta que solo hereda las propiedades directas, tanto Object.keys como Object.getOwnPropertyDescriptor solo funcionan si la propiedad está directamente declarada en el objeto y no en ninguno de sus prototipos. Y no hay ninguna forma de decir Object.getPropertyDescriptorFromHimOrHisPrototypes() así que la única forma es recorrer todos los prototipos.

function extend(obj) {
  var result = {};
  var proto = obj;

  while (proto) {
    Object.keys(proto).forEach(function(prop) {
      var descriptor = Object.getOwnPropertyDescriptor(proto, prop);
      Object.defineProperty(result, prop, descriptor);
    });

    proto = Object.getPrototypeOf(proto);
  }

  return result;
}

Pero eso tampoco funciona del todo bien porque las propiedades de los ancestros se impondrían sobre las propiedades propias del objeto. Así que primero hay que empezar por el último prototipo y acabar por el propio objeto

function extend(obj) {
  var result = {};
  var proto = obj;
  var protos = [];

  while (proto) {
    protos.push(proto);
    proto = Object.getPrototypeOf(proto);
  }

  protos.reverse().forEach(function(ancestor) {
    Object.keys(ancestor).forEach(function(prop) {
      var descriptor = Object.getOwnPropertyDescriptor(ancestor, prop);
      Object.defineProperty(result, prop, descriptor);
    });
  });

  return result;
}

Y esto ya funciona, pero le falta un detallito, mediante el property descriptor se puede poner que una propiedad no sea enumerable por lo que no se interará sobre ella con un for .. in .. ni con Object.keys pero si las podemos obtener si utilizamos Object.getOwnPropertyNames (Fuente: MDN). Así que remplazando Object.keys con Object.getOwnPropertyNames esta vez si (espero, rezo, suplico -.-) tenemos una función que crea una copia de todas las propiedades propias y heredadas de un objeto.

function ecma5extend(obj) {
  var proto = obj;
  var protos = [];
  var result = {};

  while (proto) {
    protos.push(proto);
    proto = Object.getPrototypeOf(proto);
  }

  protos.reverse().forEach(function(ancestor) {
    Object.getOwnPropertyNames(ancestor).forEach(function(prop) {
      var descriptor = Object.getOwnPropertyDescriptor(ancestor, prop);
      Object.defineProperty(result, prop, descriptor);
    });
  });

  return result;
}

Como al final el código ha quedado bastante más complejo de lo que me gustaría lo he apuntado en un Gist que podría venirles bien.

90 thoughts on “ECMAScript 5 _.extend

  1. Hmm it seems like your site ate my first comment (it was super long) so I guess I’ll just sum it up what I wrote and say, I’m thoroughly enjoying your blog. I as well am an aspiring blog blogger but I’m still new to the whole thing. Do you have any points for rookie blog writers? I’d certainly appreciate it.

  2. Howdy, i read your blog from time to time and i own a similar one and i was just curious if you get a lot of spam remarks? If so how do you stop it, any plugin or anything you can recommend? I get so much lately it’s driving me crazy so any help is very much appreciated.

  3. Appreciating the dedication you put into your site and detailed information you offer. It’s nice to come across a blog every once in a while that isn’t the same unwanted rehashed material. Fantastic read! I’ve saved your site and I’m adding your RSS feeds to my Google account.

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

  5. Hmm it looks like your site ate my first comment (it was super long) so I guess I’ll just sum it up what I submitted and say, I’m thoroughly enjoying your blog. I too am an aspiring blog blogger but I’m still new to the whole thing. Do you have any points for beginner blog writers? I’d genuinely appreciate it.

  6. Hi there! I know this is somewhat off topic but I was wondering which blog platform are you using for this site? I’m getting sick and tired of WordPress because I’ve had issues with hackers and I’m looking at options for another platform. I would be awesome if you could point me in the direction of a good platform.

  7. Howdy! I know this is somewhat off topic but I was wondering if you knew where I could locate a captcha plugin for my comment form? I’m using the same blog platform as yours and I’m having difficulty finding one? Thanks a lot!

  8. Do you have a spam problem on this website; I also am a blogger, and I was curious about your situation; we have developed some nice methods and we are looking to swap methods with others, why not shoot me an e-mail if interested.

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

  10. Hmm it appears like your website ate my first comment (it was super long) so I guess I’ll just sum it up what I wrote and say, I’m thoroughly enjoying your blog. I as well am an aspiring blog writer but I’m still new to everything. Do you have any helpful hints for newbie blog writers? I’d really appreciate it.

  11. Today, I went to the beachfront with my children. I found a sea shell and gave it to my 4 year old daughter and said «You can hear the ocean if you put this to your ear.» She placed the shell to her ear and screamed. There was a hermit crab inside and it pinched her ear. She never wants to go back! LoL I know this is entirely off topic but I had to tell someone!

  12. Greetings from Ohio! I’m bored at work so I decided to check out your website on my iphone during lunch break. I enjoy the information you provide here and can’t wait to take a look when I get home. I’m shocked at how fast your blog loaded on my mobile .. I’m not even using WIFI, just 3G .. Anyways, awesome blog!

  13. Hi! This is my first comment here so I just wanted to give a quick shout out and say I genuinely enjoy reading your posts. Can you recommend any other blogs/websites/forums that deal with the same topics? Thank you!

  14. 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 several e-mails with the same comment. Is there any way you can remove me from that service? Thank you!

  15. I’m really 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!

  16. I’ve been surfing online greater than three hours these days, yet I by no means discovered any interesting article like yours. It¡¦s lovely price enough for me. In my view, if all website owners and bloggers made just right content material as you did, the net will likely be much more useful than ever before.

  17. This design is incredible! You obviously know how to keep a reader amused. Between your wit and your videos, I was almost moved to start my own blog (well, almost…HaHa!) Great job. I really enjoyed what you had to say, and more than that, how you presented it. Too cool!

  18. It’s a shame you don’t have a donate button! I’d without a doubt donate to this excellent blog! I guess for now i’ll settle for bookmarking and adding your RSS feed to my Google account. I look forward to fresh updates and will talk about this website with my Facebook group. Chat soon!

  19. Today, I went to the beach with my children. I found a sea shell and gave it to my 4 year old daughter and said «You can hear the ocean if you put this to your ear.» She placed the shell to her ear and screamed. There was a hermit crab inside and it pinched her ear. She never wants to go back! LoL I know this is completely off topic but I had to tell someone!

  20. Thank you for any other excellent article. Where else may just anybody get that kind of information in such an ideal method of writing? I have a presentation subsequent week, and I am at the search for such info.

  21. Hey would you mind stating which blog platform you’re working with? I’m going to start my own blog soon but I’m having a hard time choosing between BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your design and style seems different then most blogs and I’m looking for something completely unique. P.S Sorry for getting off-topic but I had to ask!

  22. 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.

  23. I was wondering if you ever considered changing the layout of your website? Its very well written; I love what youve got to say. But maybe you could a little more in the way of content so people could connect with it better. Youve got an awful lot of text for only having one or two pictures. Maybe you could space it out better?

  24. Have you ever considered about including a little bit more than just your articles? I mean, what you say is important and all. However just imagine if you added some great images or videos to give your posts more, «pop»! Your content is excellent but with pics and clips, this blog could definitely be one of the very best in its niche. Superb blog!

  25. Hi, i read your blog occasionally and i own a similar one and i was just curious if you get a lot of spam comments? If so how do you stop it, any plugin or anything you can advise? I get so much lately it’s driving me mad so any help is very much appreciated.

  26. Hey would you mind stating which blog platform you’re working with? I’m looking to start my own blog in the near future but I’m having a hard time selecting between BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your design and style seems different then most blogs and I’m looking for something completely unique. P.S My apologies for being off-topic but I had to ask!

  27. Greetings from Los angeles! I’m bored at work so I decided to check out your website on my iphone during lunch break. I enjoy the info you provide here and can’t wait to take a look when I get home. I’m shocked at how quick your blog loaded on my phone .. I’m not even using WIFI, just 3G .. Anyways, very good blog!

  28. Hi would you mind letting me know which hosting company you’re utilizing? I’ve loaded your blog in 3 different internet browsers and I must say this blog loads a lot quicker then most. Can you recommend a good internet hosting provider at a reasonable price? Thanks a lot, I appreciate it!

  29. Wonderful blog! Do you have any tips for aspiring writers? I’m hoping to start my own site soon but I’m a little lost on everything. Would you recommend starting with a free platform like WordPress or go for a paid option? There are so many options out there that I’m completely overwhelmed .. Any recommendations? Bless you!

  30. Have you ever considered writing an e-book or guest authoring on other sites? I have a blog centered on the same information you discuss and would really like to have you share some stories/information. I know my readers would appreciate your work. If you’re even remotely interested, feel free to send me an email.

  31. Do you mind if I quote a couple of your articles as long as I provide credit and sources back to your blog? My blog is in the very same niche as yours and my users would genuinely benefit from some of the information you provide here. Please let me know if this alright with you. Thank you!

  32. Hey! This is my first comment here so I just wanted to give a quick shout out and tell you I really enjoy reading through your articles. Can you recommend any other blogs/websites/forums that deal with the same subjects? Appreciate it!

  33. Howdy! This post could not be written any better! Reading this post reminds me of my previous room mate! He always kept talking about this. I will forward this article to him. Pretty sure he will have a good read. Thank you for sharing!

  34. Hmm it seems like your blog ate my first comment (it was extremely long) so I guess I’ll just sum it up what I wrote and say, I’m thoroughly enjoying your blog. I as well am an aspiring blog blogger but I’m still new to everything. Do you have any helpful hints for beginner blog writers? I’d genuinely appreciate it.

  35. Woah! I’m really enjoying the template/theme of this site. It’s simple, yet effective. A lot of times it’s very hard to get that «perfect balance» between superb usability and appearance. I must say you’ve done a amazing job with this. Additionally, the blog loads extremely quick for me on Safari. Exceptional Blog!

  36. First off I would like to say excellent blog! I had a quick question that I’d like to ask if you don’t mind. I was interested to find out how you center yourself and clear your head before writing. I’ve had a hard time clearing my thoughts in getting my ideas out. I do enjoy writing however it just seems like the first 10 to 15 minutes are wasted simply just trying to figure out how to begin. Any recommendations or hints? Cheers!

  37. Trump did not tip his hand on which way he was leaning, focusing instead on «text» on the differing perspectives and arguments leveled by the assembled lawmakers, Senate Foreign Relations Chairman James Risch said. But it was clear, the Idaho Republican said, that Trump is a president who «doesn’t want to go to war.»

  38. I have been exploring for a little for any high-quality articles or weblog
    posts on this kind of space . Exploring in Yahoo I ultimately stumbled upon this website.
    Studying this information So i am satisfied to show that I’ve an incredibly just right uncanny feeling I discovered
    just what I needed. I most without a doubt will make sure to don?t fail to remember this site
    and give it a look regularly.

  39. Lionel Messi has declared that “another Copa begins now” for Argentina after seeing them scrape their way into the quarter-finals.

    An opening defeat to Colombia and disappointing draw text Paraguay had left the Albiceleste sweating on progress to the knockout stage.

    They were, however, to complete their Group B campaign with a welcome 2-0 victory over Qatar.

  40. Someone stated that you had to buy a domain name, or your blog sites weren’t seen by everyone, is that true? Do you recognize what a domain is? OTHERWISE do not address please.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *