我正在阅读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);
答案 0 :(得分:2)
Food.prototype = Object.create(Product.prototype);
您的食物原型将是产品原型的副本。这是正确的方法。
Food.prototype = Product.prototype;
您的食物原型将与您的产品原型相关联:您将在食物原型上做的每件事,如附加功能,也将被提供给产品。
采取以下实例:
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.
Removing Food.prototype = Object.create(Product.prototype); entirely
没有继承权,您将无法在食物上调用产品功能。但是,如果您仍然在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.