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.

0


source to share


1 answer


Two problems with this code:

  • Use new Plant()

    to create Fruit.prototype

    is a notoriously common anti-pattern; instead use Object.create

    and call Plant

    from Fruit

    . It doesn't really matter in your specific code, but it would be important if you wanted to get something from Fruit

    , or if you want to make it an country

    argument Plant

    .

  • You need to set constructor

    to Fruit.prototype

    if you want it to point to Fruit

    .

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;
    };
}

      

+3


source







All Articles