Javascript constructor method returning something different than expected

后端 未结 1 920
走了就别回头了
走了就别回头了 2020-12-22 11:02
function Plant() {
  this.country = \"Mexico\"
  this.isOrganic = true;
}

function Fruit(fName, fColor) {
  this.name = fName;
  this.color = fColor;
}

Fruit.proto         


        
相关标签:
1条回答
  • 2020-12-22 11:15

    Two problems with that code:

    1. Using new Plant() to create the Fruit.prototype is a sadly-common anti-pattern; instead, use Object.create and call Plant from within Fruit. It doesn't matter a lot in your specific code, but it would matter if you wanted to derive something from Fruit, or if you wanted to make country an argument to Plant.

    2. You need to set constructor on 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, as of ES2015, we have class syntax, which 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 was what the constructor method does:

    Moreover, all objects that inherit from another object also inherit a constructor property. And this constructor property is simply a property (like any variable) that holds or points to the constructor of the object.

    constructor isn't a method, it's a property that refers to the function that the prototype object is related to. JavaScript itself doesn't use constructor for anything at all, but does define that for all functions that have a prototype property, when the function is first created, the object that prototype property points to will have a constructor property pointing back at the function. But since you replace the value of prototype with a reference to a different object, you have to update the constructor property so it points back to the correct function again (if you want to be thorough, which is for the best — even though JavaScript doesn't use it, it doesn't mean that libraries don't use it).


    On really old browsers, you may have to shim Object.create. It can't be completely shimmed, but it can be sufficient for the above:

    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;
        };
    }
    
    0 讨论(0)
提交回复
热议问题