Last active
February 22, 2017 13:46
-
-
Save sminutoli/522294b2d6187939d3b26c5310d31522 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//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 | |
} | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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 | |
*/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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