javascript oop,instanceof和base class

我在 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

我觉得第一个和第二个对象都应该说它们是BaSEObject的实例.

我明白,JavaScript可能不是为了这个,但我想知道是否有办法实现这一点.

解决方法

调用Base.apply(…)不设置继承.所有这些.apply都是将其设置为第一个参数,没有其他的.调用父构造函数很重要,但这是不够的.

要做的是正确设置原型链.也就是说,您必须将Derivation1.prototype设置为继承自Base.prototype的内容.

由于构造函数的每个实例都从构造函数的原型继承,您将看到代码

Derivation1.prototype = new Base();

这是一个坏主意,您可以看到为什么:Base期望参数设置实例特定的属性(在这种情况下为name).但是我们不关心这些属性,因为我们稍后在使用Base.apply(this,…)的子构造函数中初始化它们.

所以我们需要的是从Base.prototype继承的对象,幸运的是,ECMASCript 5定义了一个可以为我们做的功能(polyfill):

Derivation1.prototype = Object.create(Base.prototype);

这将创建一个继承自Base.prototype的新对象.现在,由于您使用新对象替换了原始原型,因此您必须设置构造函数属性,使其正确指向Derivation1:

Derivation1.prototype.constructor = Derivation1;

以下是一个完整的例子.还可以看看this fiddlethis excellent answer by T.J. Crowder,它解释了基本相同的问题,但也许在一个更好的方式.

例:

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();

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...