为什么原型功能没有使用正确的版本?

时间:2018-03-20 20:32:44

标签: javascript ecmascript-6 prototype prototypal-inheritance

我试图理解使用的JS prototype继承机制。当我在浏览器中执行以下代码(例如)时,ironman.villain();函数无法从中读取name属性。我希望this成为MarvelHero对象,但它实际上是对window的引用。 ironman.summarize()也因类似原因而失败。这是为什么?

ironman.introduce();ironman.friends();正确读取this.name变量并将其打印出来。

var heroes = [];

// Hero constructor
function Hero (name, universe) {
  this.name = name;
  this.universe = universe;
  this.introduce = () => {
    return `I am ${this.name} and I belong to the ${this.universe} universe.`;
  }
  heroes.push(this);
}

// MarvelHero constructor
function MarvelHero (name) {
  this.universe = 'Marvel Comics';
  Hero.call(this, name, this.universe);
  this.friends = () => {
    return `${this.name} has friends: ${heroes.filter(hero => hero instanceof MarvelHero && hero.name !== this.name).map(hero => hero.name).join(', ')}.`;
  };
}

// DCHero constructor
function DCHero (name) {
  this.universe = 'DC Comics';
  Hero.call(this, name, this.universe);
  this.friends = () => {
    return `${this.name} has friends: ${heroes.filter(hero => hero instanceof DCHero && hero.name !== this.name).map(hero => hero.name).join(', ')}.`;
  };
}

// Parent prototype
Hero.prototype.summarize = () => {
  return `${this.name} => ${this.universe}`;
}

// Inherit from Hero's prototype
MarvelHero.prototype = Object.create(Hero.prototype);
DCHero.prototype = Object.create(Hero.prototype);

// Assign constructor prototypes to self
MarvelHero.prototype.constructor = MarvelHero;
DCHero.prototype.constructor = DCHero;

// MarvelHero prototype
MarvelHero.prototype.villain = () => {
  return `${this.name} has Loki`;
}

// DCHero prototype
DCHero.prototype.villain = () => {
  return `${this.name} has The Joker`;
}

let ironman = new MarvelHero('Ironman');
let captain = new MarvelHero('Captain America');
let spiderman = new MarvelHero('Spiderman');
let hulk = new MarvelHero('The Hulk');
let thor = new MarvelHero('Thor');
let doctor = new MarvelHero('Doctor Strange');
let panther = new MarvelHero('Black Panther');

let batman = new DCHero('Batman');
let superman = new DCHero('Superman');
let wonder = new DCHero('Wonder Woman');
let aquaman = new DCHero('Aquaman');

ironman.introduce();
ironman.friends();
ironman.villain();
ironman.summarize();

batman.introduce();
batman.friends();
batman.villain();
batman.summarize();

1 个答案:

答案 0 :(得分:0)

您的函数是在全局范围内定义的,因此这将引用窗口对象。

为了让它引用父对象,你需要它们成为对象的一部分

{
     DChero : function(name){}
}

或者将代码包装在括号中并将其用作生命