这里我有两个示例,它有两个构造函数Product
和Food
。在我的第一个示例中,当我使用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的原型链上。所以有什么不同两者之间??哪一个使用的时候?我对面向对象的概念很新。所以详细解释会很棒!!!
答案 0 :(得分:4)
两种情况下对象的属性都相同,但不是自己的属性。
aProto = { x: 1 }
a = Object.create(aProto) // a's prototype is aProto
a.y = 2
在上面的代码段中,a
会同时显示x
和y
作为属性。但是,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的更多信息。