使用.call()在JavaScript中继承对象的不同方法

时间:2015-05-04 11:08:14

标签: javascript

我正在阅读MDN example for .call(),并在我的Chrome控制台中测试了以下代码:

function Product(name, price) {
  this.name = name;
  this.price = price;

  if (price < 0) {
    throw RangeError('Cannot create product ' +
                      this.name + ' with a negative price');
  }

  return this;
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}

Food.prototype = Object.create(Product.prototype);

var cheese = new Food('feta', 5); // Food {name: "feta", price: 5, category: "food"}

在玩完之后,我发现删除Food.prototype = Object.create(Product.prototype);或将其更改为Food.prototype = Product.prototype;同样有效,并返回相同的结果。

问题:调用之间有什么区别:

1)Food.prototype = Object.create(Product.prototype);

2)Food.prototype = Product.prototype;

3)完全删除Food.prototype = Object.create(Product.prototype);

1 个答案:

答案 0 :(得分:2)

  1. Food.prototype = Object.create(Product.prototype);
  2. 您的食物原型将是产品原型的副本。这是正确的方法。

    1. Food.prototype = Product.prototype;
    2. 您的食物原型将与您的产品原型相关联:您将在食物原型上做的每件事,如附加功能,也将被提供给产品。

      采取以下实例:

      Food.prototype = Product.prototype;
      
      Food.prototype.eat = function () {
          console.log("num num num");
      };
      
      Product test = new Product("toto", 42);
      
      test.eat(); // This will output "num num num", this shouldn't.
      
      1. Removing Food.prototype = Object.create(Product.prototype); entirely
      2. 没有继承权,您将无法在食物上调用产品功能。但是,如果您仍然在Food构造函数上创建Product.call,那么您在构造函数上设置的每个属性(例如示例中的名称和价格)也将被设置。只会设置方法。

        Product = function (name, price) {
            this.name = name;
            this.price = price;
        };
        
        Product.prototype.describe = function () {
            console.log(this.name + " : " + this.price);
        };
        
        Food = function (name, price) {
           Product.call(this, name, price);
        };
        
        var cheese = new Food("cheese", 5);
        
        console.log(cheese.name); // Will work, because name was set in constructor.
        cheese.describe(); // Won't work, because you didn't copy prototypes.