Prototype chaining, Constructor, Inheritance
I'm playing with javascript prototype. I'm new to it so I've got a small question.
I'm using this article as a guide.
I've got a Product defined and a Book defined. what is the purpose of Book.prototype.constructor = Book();
this. I can't figure out. I'm able to call parent constructor with and without it both successfully.
Book.prototype = new Product;
Book.prototype.constructor = Book; // What's the purpose of this
Here's my jsFiddle link开发者_如何学编程
First off, new Product()
creates an object with all prototype variables of the Product function. So, by setting Book.prototype = new Product()
, Book inherits all prototype variables of Product.
You might think you could also say: Book.prototype = Product.prototype
, but that solution doesn't work as expected. The prototype of Book becomes a pointer to the prototype of Product, and therefore it's not a copy. If you would change something to the prototype of Book, it is actually changed in the prototype of Product, and that's not what you want.
Shortly, new Product()
creates a copy of all prototype variables.
But there is a problem with this method too. If you would create a new Book now, the Product constructor is called, instead of the Book constructor. To solve that, you need to set the constructor correctly again, and it'll work:
Book.prototype.constructor = Book;
// Note: it's not Book(), but Book, it's a reference to the function
When a constructor (which is just a function) is called with the new operator, a new object is created and the constructor's this keyword is set to a reference to that new object. The constructor function's prototype has a constructor property that points to the function.
The new now object's internal [[prototype]] property points to the constructor's public prototype. Objects don't inherit from their own public prototype.
In your code:
function Product(dName) {
this.displayName = dName;
}
function Book(dName, isbn) {
//Properties
this.ISBN = "";
// Constructor
Product.call(this, dName);
this.ISBN = isbn;
// Methods
this.getName = function() {
return this.displayName + ': ' + this.ISBN;
};
}
Book.prototype = new Product();
That sets Book's prototype to a new instance of Product (i.e. an object with Product.prototype as its internal [[prototype]]).
Book.prototype.constructor = Book(); // What's the purpose of this
You should assign a reference, not call Book, so remove the ().
Instances of Book inherit their constructor property from Book.prototype. But since it's an instance of Product, it inherits constructor from Product.prototype and so references Product. Remove the () so that Book.prototype.constructor references Book. Now instances of Book will have a constructor property inherited from Book.prototype that references Book.
It's a pretty useless property as it can be easily overwritten, as a result using the constructor property to determine if an object is an instance of something is not done very often. The instanceOf operator is also flawed, but there aren't many reasons to use either.
var b = new Book("Book", "993438403994");
alert(b.getName());
Oh I just realized based on my helpers here =).
It's not a must to do
Book.prototype.constructor = Book;
the Book constructor will be called anyway. but if Book will be extended in the future I will not be able to call it's constructor from it's child class without it.
Am I correct? if not correct me please.
精彩评论