Diff between Constructor and Prototype


#1



https://www.codecademy.com/en/courses/objects-ii/2/4?curriculum_id=506324b3a7dffd00020bf661


Replace this line with your code. 
function Dog (breed) {
  this.breed = breed;
//   this.bark = function() {
//   console.log("Woof");
// }

};

// here we make buddy and teach him how to bark
var buddy = new Dog("golden Retriever");
Dog.prototype.bark = function() {
   console.log("Woof");
 };
buddy.bark();

both these approach give the same result. what is diff between constructor and prototype and when to use what. we know there are 2 methods of creating objects? is prototype another way of creating


#2

Lots of difference, though the two are related, in a sense.

A prototype is a library of sorts, whereas a constructor is a template.

In a different respect, the constructor gives to an instance object, own property, where the prototype gives 'shared property'.

It's the reason for the new operator. It permits a constructor function to return a new object instance without using return this. All the baggage that comes with return this is own property on the return value. new strips everything except what is given in the constructor expression, itself. Baggage gone, but still in the prototype.


#3

thanks

can you please relate it to my example

when i use this inside the Dog function it displays same stuff as
Dog.prototype.bark = function() {
console.log("Woof");
};

if I dont add bark in dog prototype does that mean it will not be part of
prototype but will only be a part of constructor function Dog.


#4

In the following,

function Dog(breed) {
    this.breed = breed;
}

Dog is a class. The constructor is the template for a new object instance of the class with one direct property, this.breed. this is the new instance object held internally by the constructor function. When we invoke the constructor,

var lab = new Dog('labrador');

this is assigned to lab, the new instance. lab has an own property, breed,

console.log(lab.hasOwnProperty('breed'));    // true

Properties in the prototype object(s) are not own properties of the class instance.

Dog.prototype.bark = function () {
    console.log("Woof!");
};

As we will see,

console.log(lab.hasOwnProperty('bark'));    // false

Ideally, this is preferrable to making this a direct property of every instance since it is not unique to each instance. Sharing makes better sense when the object is the same in every instance.

function Dog(breed) {
    this.breed = breed;
    this.bark = function () {
        console.log("Woof!");
    };
}

Now when we invoke a new instance,

var collie = new Dog("collie");

console.log(collie.hasOwnProperty('bark'));    // true

will have an own property, 'bark', but then so will every other new instance have this string written directly to them. We can see that if we have 100 instance objects, there will be 100 identical strings in memory, one for every instance. This is why we should share common traits in the prototype object, rather than the constructor.

If I am making this more confusing, we can work through some more examples.


#5

Is prototype used for inheritance or it is another pattern of creating objects. Codecademy uses constructor pattern for creating objects.

I read JS has no concepts for classes Is Dog a class or a custom constructor.

Are you telling that Dog.prototype is different from function Dog(). where we add different methods in prototype and diff methods in constructor.

Is function Dog() a constructor for a new object instance of the class with one direct property

Can you elaborate on this: "This is why we should share common traits in the prototype object, rather than the constructor." - Do you mean we create objects using prototype pattern

// this will be a good example to differentiate between the two. I will be glad if you can share your views.

// prototype pattern
function Dog() {
Dog.prototype.color = "Yellow";
Dog.prototype.legs = 2;
Dog.prototype.Name = "Bushy";
}

// constructor pattern
function Dog(color, legs, name){
this.color = color;
this.legs = legs;
this.name = name;
}

many thanks


#6

Yes it is geared to inheritance, though there is a distinction between instance inheritence and class inheritance. All non-own-property methods of an instance are handed down from the constructor prototype.

A subclass, on the other hand inherits from its parent (super) class. But now there is another link in the prototype chain that can or may supercede the parent class prototype, and will almost certainly add new properties to the subclass.

function Animal() {}

inherits from Object.prototype.

function Dog() {}

also inherits from Object.prototype.

As they stand, they are two separate prototype chains with a common node, Object.prototype.

Dog.prototype = new Animal();

Now they are no longer 'siblings' in parallel, but super and sub classes in series. Dog.prototype is now linked to Animal.prototype, but still inherits from Object.prototype.

Bearing in mind the prototype, to simplify the language I'll henceforth just refer to class and take it that we understand inheritance, at least to this degree.

Dog inherits from Animal, and Animal from Object. Everything cascades down the prototype chain. What this really means is that when a property is polled, the interpreter looks up the prototype chain until it finds it.

lab = new Dog('labrador');
console.log(lab.length);    // 0

lab.length, for instance will course all the way up the chain to Object, only to find that it has a value of 0.

Granted, until now we have been calling custom custructors 'classes' when JavaScript is not a class based language, as we can see. It is prototypical. The nuances of a class based language are still present, hence they blur into the nomenclature and diction.

Here I would have to say it is not a pattern for creating objects, as such. For creating 'shared properties' (attributes and methods, methods being the big concern) is more like it.

We created the prototype when we created the constructor function. JavaScript does it for all functions, so in a sense, every function is a constructor, by default, and that is why you will often see even functions referred to as classes.

Our main objective is to write as pure a program as we can. GIGO, which we will hopefully address through validation, and, valid data in, valid data out. It should be deterministic in nature. Programmers don't keep dice in their pocket. The output should be predictable given the inputs.

I still have other answers to discuss, but this post is getting long. Will continue...


#7

Definitely. They are different. As noted above, every function comes with its own prototype object. It's the beauty in JavaScript's design... Any function can be a constructor. We extend a constructor by adding methods to its prototype.

function foo() {
    return this;
}
foo.prototype.inspect = function() {
    for (var key in this) {
        console.log(key);
    }
};
var bar = new foo();
bar.inspect();              // inspect

The second example you wrote is an exact representation of a class constructor with unique direct properties given to every instance, those passed in as parameters to the constructor function. This is the way to create unique instances, each with their own direct property values, but all with common properties.

The first example is akilter. We would never write it that way.

function Dog() {}
Dog.prototype.color = "yellow";
Dog.prototyle.numLegs = 4;
Dog.prototype.name = "Bushy";

Only one of the above make sense in the prototype: numLegs = 4. All dogs have four legs. Not all are yellow, and very few, one would suspect, are named, "Bushy", so these don't make for good prototype attributes.

What's more, since the number legs that a dog has will not likely change anytime soon in our evolutionary path, so setting it in the prototype might make sense. There is another consideration, though. What if the constructor simply overwrites a property in the parent class?

function Animal() {
    this.numLegs = 2;
}
function Dog() {
    this.numLegs = 4;
}
Dog.prototype = new Animal();

var human = new Animal();
console.log(human.numLegs);   // 2

var dog = new Dog();
console.log(dog.numLegs);     // 4

When a direct property is defined in a super class constructor, it is best to override it in the sub class constructor, rather than write it into the prototype object. It will make debugging much simpler, and the facts will be known just on reading the constructor code, without having to dig around the prototype for possible overwrites. Out in the open, so to speak, for sanity's sake.

I suspect this is going over the top in one's usual fashion, and the floor is still open for more questions. Don't be afraid to challenge me. I am accountable, and do make mistakes and throw out interpretations that may not be completely accurate. That's the fun of it... filling in our own holes, as it were.


#8

Thanks much. I will note them.

So from prototype we create constructors?
When we create a constructor do we by default create its prototype?

All objects created with object literals and with the Object constructor inherits from Object.prototype

// The userAccount object inherits from Object and as such its prototype attribute is Object.prototype.​

​var userAccount = new Object ();

​// This demonstrates the use of an object literal to create the userAccount object; the userAccount object inherits from Object; therefore, its prototype attribute is Object.prototype just as the userAccount object does above.​
​var userAccount = {name: “Mike”}

why did you say function Animal() inherits from object.prototype.

function Animal() {}

var x = new Animal();
x as such its prototype attribute (or prototype object) is Animal.prototype.

any constructor other than the Object () constructor, get their prototype from the constructor function.


#9

In a different respect, the constructor gives to an instance object, `own property', where the prototype gives 'shared property'.

Ideally, this is preferrable to making this a direct property of every instance since it is not unique to each instance. Sharing makes better sense when the object is the same in every instance.

@mtf Does this mean that direct properties, i.e. created with the class constructor, are stored as data in variables/keys multiple times, where as the shared variables/keys, i.e. created by prototype, are all references pointing to one single instance of the value's data all the instances of the class have in common?

So when it is said that a method added to a constructor extension is preferable to being added in the constructor directly, for example, this is because we'll only have one copy of the method instead of as many as there are class instances which will take up a lot of memory?

I looked at so many posts that mentioned "shared" and "own" properties and articles about the "inheritance chain" and I couldn't get it through my head at all; I mistakenly thought it had to do with creating some instances with ting a property and others without it...

@id123, you are asking all of the things I had questions about, thank you! My follow up question might be completely sideways but I am very grateful to you and @mtf for this Q&A thread regardless because I feel like I am finally starting to see the light!


#10

JavaScript does, yes, so we don't have to. It's like an empty container being shipped with every function. One we can add properties to as needed.

Because it does. A function is an object whose constructor (Function) inherits from Object,prototype. All instances spawned from the function inherit likewise.


#11

Every student has an id and their texts and notebooks. They don't need their own waste basket or stapler. For that they just go to the front of the class and use the one that is there.

A weird example. Consider also that we all have a phone, but we don't all have a bank machine. The bank machine does not need access to our phone,

The less things we give a constructor to do, the better it will perform. If it only has to make a handful of property assignments it can handle that very quickly. If it has to create a bunch of methods, it will take longer. If those methods do not need direct access to private (or class) variables they do not need to be created in the instance. That's where inheritance comes in.


#12

Thank you, @mtf. I find the classroom example especially helpful, although it did bring up up happily forgotten memories of those shared pencil sharpeners... :grin: Now I am trying to learn more when to use prototype over constructor (excluding methods) and it's a lot easier to understand what I'm reading with your metaphor in mind.


#13

Thanks Roy much needed info. Helped a lot.

So when we create a class(objects) with using a function
say function Circle(radius) {
this.radius = radius;
}

here Circle is a class and function Circle(radius) is a constructor created from Circle class. Correct.

And when we create a constructor, we are automatically defining Circle prototype which is independent of circle constructor.

So JS has mainly three imp things to note
Class - dont know why it is called class where we are creating objects
Constructor
Prototype

Appreciate if you can throw light


#14

With our custom constructor we are creating a special class of objects that have their own methods and common attributes, in addition to those inherited from further up the prototype chain.


#15

Thanks noted.

Here Bob and Mary are two objects stored in array.
var contacts = [bob, mary];

function printPerson(person) {
console.log(person.firstName + " " + person.lastName);
}

function list() {
var contactSize = contacts.length;
for (var i = 0; i < contactSize; i++) {
printPerson(contacts[i]);
}
}

var n = list;
console.log(n); // this gives me [Function: list]
Bob Jones
Mary Johnson

where as when I use
var n = list();
console.log(n); // this gives me
Bob Jones
Mary Johnson
undefined
Bob Jones
Mary Johnson

What role is function with and without parenthesis playing here


#16

I think in the first instance the value of n is the function itself (i.e. that "program", if you will) while the second n value is set to whatever the result of running the function is (in this case the results of nested function printPerson), but not sure; I defer to those more knowledgeable like @mtf.

My main motivation for posting is to share this functions exercise I just found through MDN this morning while trying to figure out "closures". I don't understand all the lessons myself yet, but it helped me wrap my mind around functions better and I thought it might help you better internalize some of the things you've asked about in your most recent post, too.


#17

This is your declared function. When you wrote this line,

var n = list;

You created a reference pointer, or essentially a copy of the function that you could then invoke with,

n();

and get the same output as list().

When you wrote,

n = list();

you assigned the return value of the function to n. Said value is not defined since there is no return, so the output was just that,

undefined

#18

So when we create a class(objects) with using a function

say function Circle(radius) {
this.radius = radius;
}

here Circle is a class and function Circle(radius) is a constructor created from Circle class. Correct.

And when we create a constructor, we are automatically defining Circle prototype which is independent of circle constructor.

So JS has mainly three imp things to note
Class - dont know why it is called class where we are creating objects
Constructor
Prototype


#19

When we create a custom class constructor, JavaScript automatically creates a link in the prototype chain directly tied to the the constructor function.

O --- Object
 |
O --- class1