我设计在JavaScript中一些类层次结构。 它工作正常,到目前为止,但我看不出如何确定对象是否是一个父类的“实例”。 例:
function BaseObject(name){
this.name = name;
this.sayWhoAmI = function(){
console.log(this.name + ' is a Derivation1 : ' + (this instanceof Derivation1));
console.log(this.name + ' is a Derivation2 : ' + (this instanceof Derivation2));
console.log(this.name + ' is a BaseObject : ' + (this instanceof BaseObject));
};
}
function Derivation1(){
BaseObject.apply(this, ['first derivation']);
}
function Derivation2(){
BaseObject.apply(this, ['second derivation']);
}
var first = new Derivation1();
var second = new Derivation2();
first.sayWhoAmI();
记录此:
first derivation is a Derivation1 : true
first derivation is a Derivation2 : false
first derivation is a BaseObject : false
而second.sayWhoAmI();
记录此:
second derivation is a Derivation1 : false
second derivation is a Derivation2 : true
second derivation is a BaseObject : false
我觉得这两个first
和second
对象应该具有说他们的实例BaseObject
。
据我所知,JavaScript可能没有为此作出的,但我不知道是否有一种方式来实现这一目标。
只有调用Base.apply(...)
不设置继承。 所有这一切.apply
确实是设置this
为第一个参数,没有别的。 它调用父类的构造函数是重要的,但它是不够的。
什么,你需要做的是正确设置原型链。 也就是说,你必须设置Derivation1.prototype
的东西,从继承Base.prototype
。
由于构造函数的每个实例从构造函数的原型继承,你会看到这样的代码
Derivation1.prototype = new Base();
这是一个坏主意 ,你已经可以看到为什么: Base
预计参数设置实例特定属性( name
在这种情况下)。 但是,我们不关心这些特性,因为我们在后面的孩子构造函数初始化它们Base.apply(this, ...)
因此,我们需要的是一个对象继承Base.prototype
,幸运的是,ECMAScript的5定义一个函数,它可以做到这一点对我们来说( 填充工具 ):
Derivation1.prototype = Object.create(Base.prototype);
这将创建一个新的对象继承Base.prototype
。 现在,因为你有一个新的对象取代了原来的原型,你必须设置的constructor
,使其正确地指向特性Derivation1
:
Derivation1.prototype.constructor = Derivation1;
下面是一个完整的例子。 也看看这个小提琴和由TJ克劳德这个优秀的答案 ,这也解释了基本相同的问题,但也许在一个更好的办法。
例如 :
function BaseObject(name){
this.name = name;
}
// move properties shared by all instances to the prototype!
BaseObject.prototype.sayWhoAmI = function() {
console.log(this.name + ' is a Derivation1 : ' + (this instanceof Derivation1));
console.log(this.name + ' is a Derivation2 : ' + (this instanceof Derivation2));
console.log(this.name + ' is a BaseObject : ' + (this instanceof BaseObject));
};
function Derivation1(){
BaseObject.apply(this, ['first derivation']);
}
Derivation1.prototype = Object.create(BaseObject.prototype);
Derivation1.prototype.constructor = Derivation1;
// some useless method of the child "class"
Derivation1.prototype.someOtherMethod = function() {
return 42;
};
var first = new Derivation1();
first.sayWhoAmI();