I am (or at least I thought I was) pretty much familiar with the concept of Hoisting in JavaScript.
Consider the following statements:
A function declaration will be hoisted along with its body, whereas a function expression will not; only the var statement will be hoisted.
“Function declarations and function variables are always moved (‘hoisted’) to the top of their JavaScript scope by the JavaScript interpreter” - Berry Cherry
Now consider the following function:
function User() {
this.name = "";
this.life = 100;
this.heal = function heal(player) {
player.life+=5;
console.log("\nHey" + player.name + "! Player " + this.name + " healed you for 5.");
}
}
... and the following users:
var Dan = new User("Danny");
var Liz = new User("Lizzy");
Say I want to add a new skill in the form of a prototype function to already defined users, like so (appended to the code):
User.prototype.uppercut = function uppercut(player) {
player.life-=10;
console.log("\nBaaam! " + player.name + ", player " + this.name + " uppercuted you for 10 damage.");
};
... and now, use said skill (add this before prototype):
Liz.uppercut(Dan);
Liz.uppercut(Dan);
... I will receive the following error:
Liz.uppercut(Dan);
^
TypeError: Liz.uppercut is not a function
Should I add a property to the User objects using a prototype, but accessing it in the code before the prototype declaration, it will work (it is hoisted):
console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana.");
User.prototype.mana = 100;
Basically this confirmed to me that the same hoisting principles which apply to functions & variables, also apply to prototypes.
Question no.1: Is this logic valid and if so, can you explain why?
Question no.2: If there a way to avoid this w/o moving the prototype expression above the prototype function call?
Thanks and have a good one!
Code snippet:
function User(name) {
this.name = name;
this.life = 100;
this.heal = function heal(player) {
player.life+=5;
console.log("Hey" + player.name + "! Player " + this.name + " healed you for 5.");
}
}
var Dan = new User("Danny");
var Liz = new User("Lizzy");
Liz.uppercut(Dan);
Liz.uppercut(Dan);
console.log(Liz.name + " you know have " + Liz.life + " life.");
User.prototype.mana = 100;
User.prototype.uppercut = function (player) {
player.life-=10;
console.log("Baaam " + player.name + "! Player " + this.name + " uppercuted you for 10 damage.");
};
console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana.");
Dan.mana = 200;
console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana.");