Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用prototype从另一个构造函数继承和在继承的构造函数内使用apply方法之间的区别_Javascript - Fatal编程技术网

Javascript 使用prototype从另一个构造函数继承和在继承的构造函数内使用apply方法之间的区别

Javascript 使用prototype从另一个构造函数继承和在继承的构造函数内使用apply方法之间的区别,javascript,Javascript,这里我有两个示例,其中有两个构造函数Product和Food。在我的第一个示例中,Food constructor通过Food.prototype=new Product()继承产品中食品构造函数创建的i console.log chicken对象在控制台上显示其属性时: Food {category: "food", name: newname, price: newprice} 代码如下: <html> <body> <script> function

这里我有两个示例,其中有两个构造函数
Product
Food
。在我的第一个示例中,Food constructor通过
Food.prototype=new Product()继承产品中食品构造函数创建的i console.log chicken对象在控制台上显示其属性时:

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>
代码:


功能产品(名称、价格){
this.name=名称;
这个价格=价格;
}
功能食品(名称、价格){
产品。应用(此,参数);
this.category=‘食品’;
}
var chicken=新食品(“鸡肉”、“40”);
原木(鸡肉);

让我困惑的是,在这两个例子中,chicken对象有三个属性类别,名称和价格。虽然在第二个示例中,食品不是从产品继承而来。我的意思是产品不在食品的原型链上。那么两者之间的区别是什么?当使用哪一个?我对面向对象的概念非常陌生。所以详细的解释将非常好

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

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
属性,该属性仅存在于原型中

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


这样可以节省对象中的空间,并确保当原型中的属性发生更改时,所有子对象都会反映该更改。它是“类”方法和属性的理想场所,因为它们不会在实例之间更改,但所有实例都必须具有它们。

在这两种情况下,对象的属性是相同的,但不是它们自己的属性

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
属性,该属性仅存在于原型中

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


这样可以节省对象中的空间,并确保当原型中的属性发生更改时,所有子对象都会反映该更改。它是“类”方法和属性的理想场所,因为它们不会在实例之间更改,但所有实例都必须具有它们。

您的原型示例是错误的:

Food.prototype=new Product('newname','newprice');
在声明一个名为Food的类型时,您强制自己创建一个Product实例,现在所有Food实例都有一个名称newname和newprice。您应该执行以下操作:

Food.prototype=Object.create(Product.prototype);
正如另一个答案已经指出的那样;原型成员在实例之间共享,但它们在实例上被调用。通常,行为是放在原型上的

第二个示例很好,因为它在创建食物实例时重复使用产品构造函数并设置特定于实例的食物成员

由于您的两个示例都没有可以共享的成员,所以在您的示例中原型没有任何用处


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

您的原型示例是错误的:

Food.prototype=new Product('newname','newprice');
在声明一个名为Food的类型时,您强制自己创建一个Product实例,现在所有Food实例都有一个名称newname和newprice。您应该执行以下操作:

Food.prototype=Object.create(Product.prototype);
正如另一个答案已经指出的那样;原型成员在实例之间共享,但它们在实例上被调用。通常,行为是放在原型上的

第二个示例很好,因为它在创建食物实例时重复使用产品构造函数并设置特定于实例的食物成员

由于您的两个示例都没有可以共享的成员,所以在您的示例中原型没有任何用处


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

它们不是独占的,一个类似于“超级”,另一个类似于“扩展”。你需要两者,调用父构造函数来继承属性,并设置原型链。如果我可以使用一个来做同样的事情,为什么我要使用另一个呢?apply方法不是继承,而是用作回调。
chicken
不会继承
产品
原型的任何内容,你需要两者。是的,构造函数中的属性,原型中没有任何内容。这根本不是继承,它只是用
This
值调用一个函数,因为
new
返回一个对象的实例,所以得到的只是一个具有这些属性的对象。这两个对象仍然是不相关的,它们不是互斥的,一个像“超级”,另一个像“扩展”。你需要两者,调用父构造函数来继承属性,并设置原型链。如果我可以使用一个来做同样的事情,为什么我要使用另一个呢?apply方法不是继承,而是用作回调。
chicken
不会继承
产品
原型的任何内容,你需要两者。是的,构造函数中的属性,原型中没有任何内容。这根本不是继承,它只是用
This
值调用一个函数,因为
new
返回一个对象的实例,所以得到的只是一个具有这些属性的对象。这两个物体还是不相关的。谢谢!!但在我的第二个示例中,如果我使用console.log(chicken.hasOwnProperty('price');它正在返回true,尽管它不是继承!!我如何解释这种情况呢?确切地说:它返回true,因为在第二个示例中,没有原型,所有的属性