我已经为这个问题困扰了几个小时,而我似乎找不到解决方案。我有一个扩展父类的类,但是我似乎无法访问在父类的构造函数中声明的变量。

borrowed my inheritance technique。它仅使用“扩展”函数来创建子类:

//In functions.js
function extend(base, sub, methods) {
    sub.prototype = Object.create(sub.prototype);
    sub.prototype.constructor = sub;
    sub.base = base.prototype;

    for(var name in methods) { sub.prototype[name] = methods[name]; }

    return sub;
}

我创建了一个名为Stimulus的类,该类可用作函数:
//In classes.js
function Stimulus(module_id, unit_id, attributes) {
    this.attributes = attributes;
    this.module_id = module_id;
    this.unit_id = unit_id;
    //create some other class variables based on this.attributes, this.module_id, and this.unit_id
}

Stimulus.prototype = {
    _getStimulus: function() { //retrieve from database }
    //other functions here
}

最后,我有了子类。我用来创建它的技术也是从上面的链接中借用的:
//In classes.js
ImageStimulus = (function() {
    var $this = function(module_id, unit_id, attributes) {
        $this.base.constructor.call(this, module_id, unit_id, attributes);
    };

    extend(Stimulus, $this, {
        initialize: function() {
            this.fixation_cross = this.attributes['Fixation Cross'] ? this.attributes['Fixation Cross'] : false;
            //do other stuff
        }
        //other functions here
    });

    return $this;
})();

一切似乎都足够简单。但是,在我的主脚本中,当我尝试运行此脚本时,我创建了对象,然后尝试运行initialize()函数,一切都崩溃了:
//In main.js
var stimulus_objects = [];

for(var i = 0; i < someLimit; i++) {
    //module_id is passed directly to this function
    var unit_id = //some source;
    var stimulus_attributes = //some source;

    stimulus_objects[i] = new ImageStimulus(module_id, unit_id, stimulus_attributes);
    stimulus_objects[i].initialize();
}

如果我检查控制台,我会看到说



它对应于ImageStimulus.initialize()中的行,在该行中我尝试调用this.attributes['Fixation Cross']

使Stimulus成为ImageStimulus的原型(prototype)似乎有些问题,因为ImageStimulus.initialize()无法访问在this.attributes类的构造函数中创建的Stimulus变量。

还有其他人看到错误吗?

我有大量使用Java,C++甚至PHP编写的OOP编程,但这是我第一次尝试JavaScript OOP,所以我觉得我可能在犯一些简单的错误。

编辑:解决了问题...以某种方式。

因此,似乎有一个相当简单的解决方案。从来没有调用过Stimulus函数,它应该已经在$this.base.constructor.call()上被调用过。在Stimulus.prototype对象中,我添加了constructor: Stimulus,现在正确调用了Stimulus。我不得不这样做似乎很奇怪(Stimulus()不能是它自己的构造函数吗?),但是它有效!
Stimulus.prototype = {
     constructor: Stimulus,
     _getStimulus: function() {...

有谁知道发生这种情况的原因以及我的修复为何起作用?我想了解我的所作所为。

最佳答案

我知道了。您要替换整个原型(prototype),因此会杀死构造函数。通过显式设置构造函数,可以将其放回原处。替代方法是直接设置原型(prototype)方法,而不是设置整个原型(prototype)。

为了使该小提琴有用,请在单击“运行”之前调出控制台并设置断点。
http://jsfiddle.net/x2v7wv6j/

//In functions.js
function extend(base, sub, methods) {
    sub.prototype = Object.create(sub.prototype);
    sub.prototype.constructor = sub;
    sub.base = base.prototype;

    for(var name in methods) { sub.prototype[name] = methods[name]; }

    return sub;
}

//In classes.js
function Stimulus(module_id, unit_id, attributes) {
    this.attributes = attributes;
    this.module_id = module_id;
    this.unit_id = unit_id;
    //create some other class variables based on this.attributes, this.module_id, and this.unit_id
}

Stimulus.prototype._getStimulus = function() { //retrieve from database
}
//other functions here

//In classes.js
ImageStimulus = (function() {
    var $this = function(module_id, unit_id, attributes) {
        $this.base.constructor.call(this, module_id, unit_id, attributes);
    };

    extend(Stimulus, $this, {
        initialize: function() {
            this.fixation_cross = this.attributes['Fixation Cross'] ? this.attributes['Fixation Cross'] : false;
            //do other stuff
        }
        //other functions here
    });

    return $this;
})();


var foo = function (module_id) {
    var stimulus_objects = [];

    var someLimit = 10;

    for(var i = 0; i < someLimit; i++) {
        //module_id is passed directly to this function
        var unit_id = "some source";//some source;
        var stimulus_attributes = "some source"; //some source;

        stimulus_objects[i] = new ImageStimulus(module_id, unit_id, stimulus_attributes);
        stimulus_objects[i].initialize();
    }
}

foo(1);

07-24 09:33