Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript

Can someone explain function.prototype.call() and function.prototype=Object.create() to me?

I understand how to write proper inheritance but I'm trying to understand exactly what I'm doing when I'm writing this so I fully understand my code. I have read a bit of the MDN but I'm not fully understanding it, help would be greatly appreciated, thanks I'm a bit confused

I understand that I'm supposed to write inheritance like this

     function Employee(){
          this.pay=' ';
          this.dept=' ';
     }

     function Manager(){
         Employee.call(this);
         this.reports=[];
     }
     Manager.prototype=Object.create(Employee.prototype);

From my understanding function.call works similar to this, so when you this as a arg it changes to where arg1 points for example, it basically allows you to change were 'this', points to

      function Employee(context,arg1,arg2,arg3){
         context.arg1=arg1;
         context.arg2=arg2;
         context.arg3=arg3;
      }

So function.call doesn't create inheritance because it simply copies the properties to the new function and object and doesn't force it to walk up the prototype chain so you're repeating your self and from my understanding then its only use would to to copy arguments from another function.

this quasi-inheritance works if I just use Function.call with constructors, that is if I simply copy the values into a new object, as such

      function Employee(){
           this.pay=' ';
           this.dept=' ';
       }
      function Manager(){
          Employee.call(this);
          this.reports=[];
      }
//this works!!
/*but all the objects created with Manager() will have all the properties from Employee copied directly into it, and it doesnt walk the prototype chain to find them*/

From my understanding Object.create(function.prototype) creates a new object so its no referencing the original functions prototype and create inheritance, this works and creates inheritance like I would expect, where it walks up a prototype chain and doesn't copy the properties into a new object

       var animal={
           moves: true
        }

       var snake = Object.create(animal);
           snake.noLeggs=true;
           snake.coldBlooded= true;

       var python= Object.create(snake);
           python.size='large';
        //if I were to type python.moves it would return true
       //but python doesn't have a property named pay so its walking up the prototype chain to find it

however this doesn't seem to work with constructor functions so I'm a bit confused as to what I am doing wrong or what the purpose of function.prototype=Object.create(super Function.prototype); That is you cant seem to use inheritance from my experience to create a prototype chain, for example the following wouldn't work for me

      function Employee(){
           this.pay=' ';
           this.depth=' ';
      }

      function Manager(){
          this.reports=[];
      }
      Manager.prototype=Object.create(Employee.prototype);
      //however if I were to type var tom= new Manager(); tom.pay, pay would return "undefined"
      //so it appears I need Function.call()

So it seems to me this isn't doing anything, so what am I missing, what am I doing wrong and if I'm not doing anything wrong what is the purpose and what am I not understanding? The only way I can get it to work is with using Function.call and it seems to work the same way with or without function.prototype=Object.create(super function.prototype);, but it would be preferably if it walked up a prototype chain so to code dry.

1 Answer

Look at it this way: right now, the prototype of Employee is just Object(as far as I can tell). So making the prototype of Manager be Employee.prototype is almost meaningless, since that's what it already is. However I believe you can do this:

Manager.prototype = Object.create(new Employee());

This way the Manager's prototype is an instance of Employee. Your call statement is essentially doing the same thing: it calls the Employee function and makes Manager the context.