【问题标题】:javascript oop, instanceof and base classjavascript oop、instanceof 和基类
【发布时间】:2012-07-24 13:18:26
【问题描述】:

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

我觉得firstsecond 对象都应该说它们是BaseObject 的实例。

我知道 JavaScript 可能不是为此而开发的,但我想知道是否有办法实现这一点。

【问题讨论】:

  • 只调用Base.apply(...) 不会设置继承。您必须正确设置原型。请参阅:jsfiddle.net/fkling/wJE6s。也看看这个问题的解释:stackoverflow.com/questions/3145700/…
  • Felix 你应该把这个写成答案,这正是我所需要的,你的小提琴简单地展示了它。不要让别人窃取你的声誉!
  • 同意他应该添加一个答案,但他可能并不担心将他的声望提高 0.01%!
  • 太晚了,我太累了,无法提供完整的答案,对不起。现在添加一个,我希望它可以理解。如果有任何不清楚的地方,请随时发表评论。

标签: javascript oop polymorphism


【解决方案1】:

仅调用Base.apply(...) 不会设置继承。 .apply 所做的只是将this 设置为第一个参数,仅此而已。调用父构造函数很重要,但还不够。

您要做的是正确设置原型链。也就是说,您必须将 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 的新对象。现在,由于您将原始原型替换为新对象,因此您必须设置 constructor 属性,使其正确指向 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();

【讨论】:

    猜你喜欢
    • 2014-04-29
    • 1970-01-01
    • 2012-07-13
    • 2015-02-22
    • 1970-01-01
    • 2012-05-28
    • 1970-01-01
    • 1970-01-01
    • 2013-07-26
    相关资源
    最近更新 更多