Javascript constructor method returns something different than expected
function Plant() {
this.country = "Mexico"
this.isOrganic = true;
}
function Fruit(fName, fColor) {
this.name = fName;
this.color = fColor;
}
Fruit.prototype = new Plant();
var abanana = new Fruit("Banana", "Yellow")
console.log(abanana.constructor)
So in my code, I was trying to play around with prototype inheritance. Every time I create a new Fruit instance (var aFruit = new Fruit ()), the prototype of the new instances is assigned the prototype from the Fruit constructor, which is Fruit.prototype.
So why is abanana.constructor not
[function: Fruit]
but
[function: Plant]?
I thought this is what the constructor method does:
In addition, all objects that inherit from another object also inherit the constructor property. And that constructor property is just a property (like any variable) that contains or points to the constructor of an object.
source to share
Two problems with this code:
-
Use
new Plant()
to createFruit.prototype
is a notoriously common anti-pattern; instead useObject.create
and callPlant
fromFruit
. It doesn't really matter in your specific code, but it would be important if you wanted to get something fromFruit
, or if you want to make it ancountry
argumentPlant
. -
You need to set
constructor
toFruit.prototype
if you want it to point toFruit
.
So:
function Plant() {
this.country = "Mexico"
this.isOrganic = true;
}
function Fruit(fName, fColor) {
Plant.call(this); // **
this.name = fName;
this.color = fColor;
}
Fruit.prototype = Object.create(Plant.prototype); // **
Fruit.prototype.constructor = Fruit; // **
Of course, with ES2015 we have the syntax class
you can use today with a transpiler (or if you only need to support current versions of Chrome and Firefox):
class Plant {
constructor() {
this.country = "Mexico";
this.isOrganic = true;
}
class Fruit extends Plant {
constructor(fName, fColor) {
super();
this.name = fName;
this.color = fColor;
}
}
I thought this is what the constructor method does:
In addition, all objects that inherit from another object also inherit the constructor property. And that constructor property is just a property (like any variable) that contains or points to the constructor of an object.
constructor
is not a method, it is a property that refers to the function the object is associated with prototype
. JavaScript itself does not use constructor
for anything at all, but defines that for all functions that have a property prototype
, when the function is first instantiated, the object that the property points prototype
to will have a constructor
property that returns the function. But since you are replacing the value with a prototype
reference to another object, you need to update the property constructor
so that it reverts back to the correct function again (if you want to be careful, which is best.Although JavaScript doesn't use it, that doesn't mean libraries don't use it).
In really old browsers, you may need to shim Object.create
. It cannot be fully adjusted, but it may be sufficient for this:
if (!Object.create) {
Object.create = function(p, props) {
if (typeof props !== "undefined") {
throw new Error("The second argument of Object.create cannot be shimmed.");
}
function ctor() { }
ctor.prototype = p;
return new ctor;
};
}
source to share