javascript - 构造函数原型(prototype)——继承困惑

标签 javascript constructor prototype

我从定义 2 个独立的构造函数开始。

var Sword = function (attack,price){
 this.attack = attack;
 this.price = price;
};

var LegendarySword = function (){
 this.instantKill = true;
};

这些构造函数创建的对象显然彼此不相关。

var sword = new Sword(1, 100);
console.log(sword);

//Object
    attack: 1
    price: 100
    __proto__: Object


var superSword = new LegendarySword();
console.log(superSword);

//Object
    instantKill: true
    __proto__: Object

我现在希望“类”LegendarySword 的所有实例都具有剑“类”的特征属性,即攻击和价格值。这是因为所有的传奇剑最终都是剑,但具有一些独特的属性(例如“instantKill”)。

所以,在阅读了有关原型(prototype)和继承的内容之后,我发现我可以微笑着这样做:

LegendarySword.prototype = new Sword();

我对这行的理解是,在构造 LegendarySword 类的新对象时,除了 LegendarySword 已有的构造函数之外,我还使用了 Sword 的构造函数。我期望 LegendarySword 对象获得攻击和价格属性,但同时我不期望 Sword 对象获得 instantKill 属性。

我还希望我现在能够在 LegendarySword 构造函数中提供参数:

var superSword2 = new LegendarySword (5, 1000);

我希望它接受参数,就像 Sword 的构造函数一样,但它显然没有:

console.log(superSword2.attack); // results to undefined (which proves that it has them dug in somewhere in the __proto__,  which is so indeed)

看起来我仍然可以从不同的 Angular 解决问题。我认为,如果我在某种程度上不必要地使构造函数复杂化并向 Sword 添加新方法并在创建新的 Legendary Sword 对象时调用这些方法并传递参数:

var Sword = function (attack,price){
 this.attack = attack;
 this.price = price;
    this.setAttack = function(attack){
    this.attack = attack;
};
this.setPrice = function(price){
    this.price = price;
};
};

var LegendarySword = function (attack, price){
 this.instantKill = true;
 this.setAttack(attack);
 this.setPrice(price);

};

LegendarySword.prototype = new Sword();

var sword = new Sword(1, 100);
console.log(sword);// gives correct object attributes

var superSword = new LegendarySword(10,5000);
console.log(superSword); // gives correct object attributes

但这真的很丑陋,我的问题是为什么在调整构造函数的原型(prototype)时 Javascript 无法确定需要添加新属性?这对我来说太直观了。

是否有其他方法可以解决这个问题?

最佳答案

I would expect this to take the arguments, just like Sword constructor does, but it obviously does not:

您不应该期望,修改构造函数的原型(prototype)不会修改构造函数本身。

> console.log(superSword2.attack);
> // results to undefined
> // (which proves that it has them dug in somewhere in
> //  the __proto__,  which is so indeed)

这并不能证明这一点。您不知道该属性是否存在,因为访问不存在的属性也会返回 undefined(这是本例中实际发生的情况)。

当你这样做时:

LegendarySword.prototype = new Sword();

您只需将 LegendarySword 的默认原型(prototype)替换为 Sword 的实例,它不会修改 LegendarySword 本身,所以 构造函数未添加攻击价格 属性。

如果您希望 LegendarySword 实例拥有与Sword 相同的属性,您可以这样做:

var LegendarySword = function (attack, price){

  // Add Sword properties
  Sword.call(this, attack, price);

  // Add LegendarySword properties
  this.instantKill = true;
};

这会设置所需的原型(prototype) 链并使用Sword 属性初始化LegendarySword

关于javascript - 构造函数原型(prototype)——继承困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28004432/

相关文章:

具有公共(public) getter 和 setter 方法的 JavaScript 对象

javascript - 从 JSON API(从一台服务器)获取数据并将其显示在 HTML 上(到另一台服务器)

javascript - 我可以将原型(prototype)应用于 js 构造函数(而不是它创建的实例)吗?

F# 备用构造函数为(可变的)let 绑定(bind)赋值

javascript - __proto__ 用于 IE9 或 IE10

Addy Osmani 的 Javascript 装饰器模式

javascript - 当我的页面在 IE 中加载时,窗口立即跳到其他窗口后面

来自数据库的javascript代码

javascript - 检查时间段条件不可用

作为另一个对象的一部分的对象的 C++ 构造函数