使用原型从另一个构造函数继承并在继承的构造函数中使用apply方法之间的区别

时间:2014-09-05 19:23:51

标签: javascript

这里我有两个示例,它有两个构造函数ProductFood。在我的第一个示例中,当我使用Food构造函数创建的console.log鸡对象时,Food constrcutor通过Food.prototype=new Product();继承产品in在控制台上显示它的属性:

Food {category: "food", name: newname, price: newprice} 

这是代码:

<html>
<body>
<script>
function Product(name, price) {
  this.name = name;
  this.price =price;

}

function Food(name, price) {

  this.category = 'food';
}
Food.prototype=new Product('newname','newprice');
var chicken = new Food('chicken','40');

console.log(chicken);
</script>
</body>
</html>

现在这是第二个示例,我删除了Food.prototype=new Products('newname,'newprice');,而我在Food构造函数中使用了Product.apply(this,arguments);。在控制台中它显示了相同的结果:

Food {name: "chicken", price: "40", category: "food"} 

代码:

<html>
<body>
<script>
function Product(name, price) {
  this.name = name;
  this.price =price;

}

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

var chicken = new Food('chicken','40');

console.log(chicken);
</script>
</body>
</html>

令我困惑的是,在两个例子中,鸡对象有三个属性类别,名称和价格。虽然在第二个例子中食物不是继承自Product.I意味着产品不在Food的原型链上。所以有什么不同两者之间??哪一个使用的时候?我对面向对象的概念很新。所以详细解释会很棒!!!

2 个答案:

答案 0 :(得分:4)

两种情况下对象的属性都相同,但不是自己的属性

aProto = { x: 1 }
a = Object.create(aProto) // a's prototype is aProto
a.y = 2

在上面的代码段中,a会同时显示xy作为属性。但是,x是继承的,y不是,您可以使用以下方式验证:

Object.hasOwnProperty(a, 'x') // false
Object.hasOwnProperty(a, 'y') // true

换句话说,对于a的每个副本,都会有y属性;但是所有这些属性似乎都具有x属性,该属性仅存在于原型中。

区别在于克隆属性与使用父对象中相同属性的区别。

这样可以节省对象中的空间,并确保当原型中的属性发生更改时,所有子项都会反映出该更改。它是&#34; class&#34;的理想之地。方法和属性,因为它们不会跨实例进行更改,但所有实例都必须具有这些方法和属性。

答案 1 :(得分:0)

您的原型示例错误:

Food.prototype=new Product('newname','newprice');

在声明一个名为Food的类型时,你强迫自己创建一个Product实例,现在所有的Food实例都有一个newname和newprice的名字。您应该执行以下操作:

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

正如另一个答案已经指出的那样;原型成员在实例之间共享,但它们在实例上调用。通常会将行为放在原型上。

您的第二个示例很好,因为它在创建Food实例时重新使用Product构造函数并设置特定于实例的Food成员。

由于您的示例都没有可以共享的成员,因此示例中没有原型。

您可以阅读有关原型和构造函数here的更多信息。