【问题标题】:Javascript constructor method returning something different than expectedJavascript 构造函数方法返回的东西与预期不同
【发布时间】:2015-07-28 11:02:36
【问题描述】:
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]?

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

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

【问题讨论】:

标签: javascript


【解决方案1】:

该代码有两个问题:

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

  2. 如果你想让Fruit.prototype指向Fruit,你需要在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 属性指向的对象将具有 @987654340 @ 属性指向函数。但是由于您替换 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;
    };
}

【讨论】:

  • 你的意思是从水果中提取一些东西?
  • @Jwan622:与您从 Plant 导出 Fruit 的方式相同。
  • 我得到了什么?我只是将 Fruit 的原型对象设置为植物对象?
  • @Jwan622:这是派生的,在某种程度上这个词在 JavaScript 中意味着任何东西。
猜你喜欢
  • 2020-11-27
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 2018-02-07
  • 1970-01-01
  • 2014-04-09
  • 2016-11-10
相关资源
最近更新 更多