我有以下简单的继承模式,我想知道在构造函数中是否可以按照我的方式调用方法(基本上,使用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
财产并不总是我们在想什么(从我在这里和那里读到的)我不确定这些东西如何影响最终的对象。
感谢您的启发!
答案 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.super
,this.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