Skip to content

Instantly share code, notes, and snippets.

@sminutoli
Last active February 22, 2017 13:46
Show Gist options
  • Save sminutoli/522294b2d6187939d3b26c5310d31522 to your computer and use it in GitHub Desktop.
Save sminutoli/522294b2d6187939d3b26c5310d31522 to your computer and use it in GitHub Desktop.
//ES5
var SpecialItem = Object.create(Item); //delego todos los mensajes que no conozco a Item
Object.assign( SpecialItem, {
updateQuality: function fnUpdateQuality(){
if(this.quality > 10) return; // si tengo mas de 10, no redirijo el mensaje a mi prototipo
Object.getPrototypeOf(this).updateQuality.call(this); // hago que el mensaje siga la cadena de prototipos
}
});
// ES2015
var SpecialItem = {
__proto__: Item, //delego todos los mensajes que no conozco a Item
updateQuality(){
if(this.quality > 10) return; // si tengo mas de 10, no redirijo el mensaje a mi prototipo
super.updateQuality(); // hago que el mensaje siga la cadena de prototipos
}
};
SpecialItem.quality = 10;
SpecialItem.update();
SpecialItem.quality; // 10
// ES2015
var SpecialItem = Object.setPrototypeOf({
updateQuality(){
if(this.quality > 10) return; // si tengo mas de 10, no redirijo el mensaje a mi prototipo
super.updateQuality(); // hago que el mensaje siga la cadena de prototipos
}
}, Item);
SpecialItem.quality = 10;
SpecialItem.update();
SpecialItem.quality; // 10
// ES2015 gotcha
var SpecialItem = Object.create(Item); //delego todos los mensajes que no conozco a Item
Object.assign( SpecialItem, {
updateQuality(){
if(this.quality > 10) return; // si tengo mas de 10, no redirijo el mensaje a mi prototipo
super.updateQuality(); // hago que el mensaje siga la cadena de prototipos
}
});
SpecialItem.quality = 10;
SpecialItem.update(); // error, no encuentra el mensaje updateQuality, ya que super se definió lexicamente! en ese caso super siempre va a apuntar a Object.prototype
/* para solucionar esto... */
var SpecialItem = Object.create(Item); //delego todos los mensajes que no conozco a Item
var toFixProto = {
updateQuality(){
if(this.quality > 10) return; // si tengo mas de 10, no redirijo el mensaje a mi prototipo
super.updateQuality(); // hago que el mensaje siga la cadena de prototipos
}
};
Object.setPrototypeOf(toFixProto, Item); // al ejecutarse setPrototypeOf, se recalcula super dentro de la función
Object.assign(SpecialItem, toFixProto);
SpecialItem.quality = 10;
SpecialItem.update(); // OK!
/*
El problema de esta solución es que si otros objetos delegaban en toFixProto, estoy cambiando toda la cadena de prototipos
*/
// ES2015 gotcha 2
var SpecialItem = {
__proto__: Item, //delego todos los mensajes que no conozco a Item
updateQuality(){
if(this.quality > 10) return; // si tengo mas de 10, no redirijo el mensaje a mi prototipo
super.updateQuality(); // hago que el mensaje siga la cadena de prototipos
},
updateQuality2(){
if(this.quality > 10) return;
Object.getPrototypeOf(this).updateQuality.call(this); // sin super a propósito, ver abajo!
}
};
var Product = {
quality: 1,
updateQuality(){
this.quality-=5;
}
};
/* en este caso quiero reutilizar la logica de solo redirigir el mensaje updateQuality a mi prototipo, si quality < 10 */
var SpecialProduct = {
__proto__: Product,
updateQuality: SpecialItem.updateQuality,
updateQualityFixed: SpecialItem.updateQuality2
};
SpecialProduct.quality = 9;
SpecialProduct.updateQuality();
SpecialProduct.quality; // 10! en vez de 4 como esperaría... eso demuestra que la palabra super sigue apuntando lexicamente a donde refiera el contexto en donde fue generada la función...
SpecialProduct.updateQualityFixed();
SpecialProduct.quality; // 5 como esperamos, al no usar super (que se fija lexicamente) el tipo resuelve dinámicamente el prototipo con Object.getPrototypeOf()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment