【问题标题】:difference between inheriting from another constructor using prototype and using apply method inside the constructor which inherits使用原型从另一个构造函数继承和在继承的构造函数中使用 apply 方法之间的区别
【发布时间】:2014-10-30 19:22:44
【问题描述】:

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

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>

让我感到困惑的是,在这两个例子中,鸡肉对象都有三个属性类别,名称和价格。虽然在第二个例子中,食物不是从产品继承的。我的意思是产品不在食物的原型链上。那么有什么区别两者之间??什么时候使用??我对面向对象的概念还很陌生。所以详细的解释会很棒!!!

【问题讨论】:

  • 它们不是排他的,一个像“super”,一个像“extends”。两者都需要,调用父构造函数继承属性,设置原型链。
  • 如果我可以用一个做同样的事情,我为什么要使用另一个??
  • apply 方法不是继承而是用作回调..
  • chicken 不会从Product 的原型继承任何东西,你需要两者。
  • 是的,来自构造函数的属性,没有来自原型。这根本不是继承,它只是调用具有this 值的函数,并且由于new 返回一个对象的实例,所以你得到的只是一个具有这些属性的对象。这两个对象仍然不相关。

标签: javascript


【解决方案1】:

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

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

在上面的 sn-p 中,a 将同时显示 xy 作为属性。但是,x 是继承的,y 不是,您可以使用以下方法进行验证:

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

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

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

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

【讨论】:

  • 谢谢!!但是在我的第二个示例中,如果我执行 console.log(chicken.hasOwnProperty('price'));它返回 true ,虽然它没有继承!!我该如何解释这种情况。
  • 完全正确:它返回 true 因为在第二个示例中没有原型,所有属性都设置在 a 对象本身上。第一个示例将显示不是own 的属性
【解决方案2】:

您的原型示例是错误的:

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

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 2014-01-01
    • 2014-11-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多