繁体   English   中英

Javascript构造函数方法返回与预期不同的东西

[英]Javascript constructor method returning 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)

所以在我的代码中,我试图玩弄原型继承。 每次我创建一个 Fruit 的新实例(var aFruit = new Fruit())时,新实例的原型都会从 Fruit 构造函数中分配一个原型,即 Fruit.prototype。

那么为什么 abanana.constructor 不是

[function: Fruit] 

[function: Plant]?

我认为这就是构造函数方法的作用:

此外,从另一个对象继承的所有对象也继承了构造函数属性。 而这个构造函数属性只是一个属性(就像任何变量一样),它持有或指向对象的构造函数。

该代码有两个问题:

  1. 使用new Plant()创建Fruit.prototype是一种可悲的常见反模式; 相反,使用Object.create并从Fruit调用Plant 在您的特定代码中并不重要,但是如果您想从Fruit派生出某些东西,或者您是否想让country成为Plant的参数,这将很重要。

  2. 如果您希望它指向Fruit则需要在Fruit.prototype上设置constructor

所以:

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;              // **

当然,从 ES2015 开始,我们有class语法,您现在可以将其与转译器一起使用(或者如果您只需要支持当前版本的 Chrome 和 Firefox):

class Plant {
    constructor() {
        this.country = "Mexico";
        this.isOrganic = true;
}

class Fruit extends Plant {
    constructor(fName, fColor) {
        super();
        this.name = fName;
        this.color = fColor;
    }
}

我认为这就是构造函数方法的作用:

此外,从另一个对象继承的所有对象也继承了构造函数属性。 而这个构造函数属性只是一个属性(就像任何变量一样),它持有或指向对象的构造函数。

constructor不是一个方法,它是一个属性,引用prototype对象相关的函数。 JavaScript 本身根本不使用constructor ,但确实为所有具有prototype属性的函数定义了,当函数第一次创建时, prototype属性指向的对象将具有一个指向函数的constructor属性。 但是由于您对不同对象的引用替换prototype的值,因此您必须更新constructor属性,使其再次指向正确的函数(如果您想彻底,这是最好的——即使JavaScript没有不使用它,并不意味着图书馆不使用它)。


在非常旧的浏览器上,您可能需要填充Object.create 它不能完全填充,但对于上述情况就足够了:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM