title: Property added to a JS object as a prototype is hoisted, whereas a prototype function is not
body: <p>I am (or at least I thought I was) pretty much familiar with the concept of <a href="https://developer.mozilla.org/en-US/docs/Glossary/Hoisting" rel="nofollow noreferrer">Hoisting</a> in JavaScript.</p>
  
  <p>Consider the following statements:</p>
  
  <blockquote>
    <p>A <strong>function declaration</strong> will be hoisted along with its body, whereas a <strong>function expression</strong> will not; <strong>only the var statement will be hoisted</strong>.</p>
    
    <p>“<strong>Function declarations</strong> and <strong>function variables</strong> are always moved (‘hoisted’) to the top of their JavaScript scope by the JavaScript interpreter” - Berry Cherry</p>
  </blockquote>
  
  <p>Now consider the following function: </p>
  
  <pre><code>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.");
      } 
  }
  </code></pre>
  
  <p>... and the following users:</p>
  
  <pre><code>var Dan = new User("Danny");
  var Liz = new User("Lizzy");
  </code></pre>
  
  <p>Say I want to add a new <strong><em>skill</em></strong> in the form of a prototype function to already defined users, like so (appended to the code):</p>
  
  <pre><code>User.prototype.uppercut = function uppercut(player) {
      player.life-=10;
      console.log("\nBaaam! " + player.name + ", player " + this.name + " uppercuted you for 10 damage.");
  };
  </code></pre>
  
  <p>... and now, use said <strong><em>skill</em></strong> <strong><em>(add this before prototype)</em></strong>:</p>
  
  <pre><code>Liz.uppercut(Dan);
  Liz.uppercut(Dan);
  </code></pre>
  
  <p>... I will receive the following error: </p>
  
  <pre><code>Liz.uppercut(Dan);
      ^
  TypeError: Liz.uppercut is not a function
  </code></pre>
  
  <p>Should I add a property to the User objects using a prototype, but accessing it in the code before the prototype declaration, it will <strong><em>work</em></strong> (it is hoisted):</p>
  
  <pre><code>console.log("Hey there " + Dan.name + "! You have " + Dan.mana + " remaining mana.");
  User.prototype.mana = 100;
  </code></pre>
  
  <p>Basically this confirmed to me that the same <strong><em>hoisting</em></strong> principles which apply to functions &amp; variables, also apply to prototypes. </p>
  
  <p><strong>Question no.1:</strong> Is this logic valid and if so, can you explain why?</p>
  
  <p><strong>Question no.2:</strong> If there a way to avoid this w/o moving the prototype expression above the prototype function call?</p>
  
  <p><strong>Thanks</strong> and have a good one!</p>
  
  <p><strong>Code snippet:</strong>
  <div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>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.");</code></pre>
  </div>
  </div>
  </p>