Reputation: 988
I am trying to understand prototypal pattern and constructor pattern in JavaScript. I read that they are equivalent. So, I thought of intermixing them and got stumped by the results:
Defining the constructor:
function Person(name){
this.name = name;
this.describe = function(){ return "Name: "+this.name };
};
Testing the constructor:
munish = new Person('Munish'); // Person { name="Munish", describe=function()}
munish.constructor; // Person(name)
munish.constructor.name; // "Person"
Person.prototype; // Person {}
Object.getPrototypeOf(munish) === Person.prototype; // true
Now, trying to use dunder proto and C.prototype to create new objects
nitin = {
name: 'Nitin',
__proto__: Person.prototype,
// __proto__: Object.getPrototypeOf(munish), // same as above
}
nitin.describe(); // TypeError: nitin.describe is not a function
Taking another approach by using Object.create() to create new objects
nitin = Object.create(Person.prototype);
nitin.name = 'Nitin';
nitin.describe(); // TypeError: nitin.describe is not a function
Or, if I try
nitin = Object.create(Object.getPrototypeOf(new Person('Nitin')));
nitin.describe(); // TypeError: nitin.describe is not a function
Why the code is throwing TypeError? I spent almost a full day trying to figure out where I went wrong. Any clues?
Upvotes: 0
Views: 35
Reputation: 1074335
Your nitin
object doesn't have a describe
property because it's not on the prototype. It's a property you're adding to the instance when the constructor is called. If you never call the constructor, it's never added. Just referring to Person.prototype
doesn't call Person
.
You could put describe
on Person.prototype
:
function Person(name){
this.name = name;
}
Person.prototype.describe = function(){ return "Name: "+this.name; };
And then
var nitin = Object.create(Person.prototype);
nitin.name = "Nitin";
nitin.describe();
But of course, you have to duplicate the logic from the constructor every time you do that. If you're going to have a constructor function, it's best to actually use it. If you have a reason for constructing the object without using new
, you can still use the constructor to initialize it. (Despite their names, constructors don't actually construct anything, they initialize things. new
is what does the actual construction — or, of course, Object.create
.) Here's how:
var nitin = Object.create(Person.prototype);
Person.call(nitin, "Nitin");
nitin.describe();
Of course, that's just a really long-winded way to write:
var nitin = new Person("Nitin");
nitin.describe();
Upvotes: 1