从javascript构造函数

时间:2015-07-20 19:03:50

标签: javascript inheritance methods constructor

我有以下简单的继承模式,我想知道在构造函数中是否可以按照我的方式调用方法(基本上,使用this代替&#34 ;超级原型"。

家长班Pet

function Pet(name) {
  this.name = name;
  this.nickname = name;

  this.adopt();
}

Pet.prototype.adopt = function() {
  this.nickname = 'Cutty ' + this.name;
}

Pet.prototype.release = function() {
  this.nickname = null;
}

Pet.prototype.cuddle = function() {
  console.log(this.name + ' is happy');
}

子类,Lion

function Lion(name) {
  Pet.prototype.constructor.apply(this, arguments); // super(name)
  this.cuddle();
  this.release();
}
Lion.inherits(Pet);

Lion.prototype.adopt = function() {
  // DTTAH
}

Lion.prototype.release = function() {
  Pet.prototype.release.call(this);
  console.log('Thanks for releasing ' + this.name);
}

inherits帮助者(我知道polyfills很糟糕)

Function.prototype.inherits = function(Parent) {
  function ProtoCopy() {}
  ProtoCopy.prototype = Parent.prototype;

  this.prototype = new ProtoCopy();
  this.prototype.constructor = this;
}

我的宠物被实例化为var lion = new Lion('Simba')

在Lion构造函数中,
在调用子/父类方法时,我可以继续使用this吗?或者我应该直接使用父原型的方法? (如对super()release()的伪调用)

我要问的原因是:

  • this在运行时替换
  • constructor财产并不总是我们在想什么(从我在这里和那里读到的)

我不确定这些东西如何影响最终的对象。

感谢您的启发!

2 个答案:

答案 0 :(得分:1)

  

在构造函数中使用MyClass.prototype.fn.call(this)this.fn === MyClass.prototype.fn有什么区别?

这不是特定于构造函数,它在实例上调用的所有函数(方法)中都是相同的。

实际上除this时的字符数没有太大区别,它们的行为完全相同。但是,这个假设并不总是正确的 - MyClass.prototype可能不会直接从this.fn继承,而是子类实例,并且该子类可能会覆盖 this.constructor方法。

哪一个是正确的?事实上,两者都是。如果您知道其中的差异,可以根据具体情况选择合适的一种。其他语言在此处有不同的默认期望,另请参阅in this answer

请注意,您不能用this.fn()替换类引用,它也会被覆盖。在合理的设置 1 中,this.constructor.prototype.fn.call(this)总是等同于this.constructor

这类似于超级调用必须显式引用超类的原因,而不依赖于实例属性(例如this.superthis.fn或类似的东西)。

1:其中.constructor是从原型继承的常用方法,而不是自己的特定于实例的方法,并且每个原型都有.prototype指向相应的构造函数{{1}} {{1}} 1}}它是。

答案 1 :(得分:0)

简化问题,请考虑ES6中的以下代码:

class Pet {
  constructor (name) {
    this.name = name;
    this.talk();
  }
  talk () {
    console.log('My name is ' + this.name);
  }
}

class Lion extends Pet {
  constructor (name) {
    super(name);
  }
  talk () {
    super.talk();
    console.log('I am a lion.');
  }
}

相当于:

function Pet (name) {
  this.name = name;
  this.talk();
}
Pet.prototype.talk = function () {
  console.log('My name is ' + this.name);
};

function Lion (name) {
  Pet.call(this, name);
}

// inheritance:
Lion.prototype = Object.create(Pet.prototype);
Lion.prototype.constructor = Lion;

// override .talk
Lion.prototype.talk = function () {
  Pet.prototype.talk.call(this);
  console.log('I am a lion');
}

运行new Lion('Bobby')日志:

My name is Bobby
I am a lion

进一步阅读:http://eli.thegreenplace.net/2013/10/22/classical-inheritance-in-javascript-es5