【问题标题】:Accessing variables in the parent class访问父类中的变量
【发布时间】:2015-08-07 19:29:32
【问题描述】:

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

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 的原型似乎出了点问题,因为ImageStimulus.initialize() 无法访问在Stimulus 类的构造函数中创建的this.attributes 变量。

其他人看到错误了吗?

我在 Java、C++ 甚至 PHP 方面有相当多的 OOP 编程,但这是我第一次尝试 JavaScript OOP,所以我觉得我可能犯了一些简单的错误。

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

所以似乎有一个相当简单的解决方案。 Stimulus 函数从未被调用过,它应该在$this.base.constructor.call() 的行上被调用。在Stimulus.prototype 对象中,我添加了constructor: Stimulus,现在Stimulus 被正确调用。我必须这样做似乎很奇怪(Stimulus() 不应该是它自己的构造函数吗?),但它有效!

Stimulus.prototype = {
     constructor: Stimulus,
     _getStimulus: function() {...

有谁知道为什么会发生这种情况以及为什么我的修复有效?我试图了解我做了什么。

【问题讨论】:

  • stimulus_attributesundefined 然后 attributesundefined
  • 我在new ImageStimulus 之前放了一个控制台日志,stimulus_attributes 看起来与预期的完全一样。我还在输入ImageStimulus 构造函数后立即记录了它,它按预期打印。但是,如果我尝试在 Stimulus() 函数中记录它,则不会打印任何内容;该函数甚至没有被调用。我想知道是什么原因造成的?
  • 如果您使用return extend(Stimulus, $this, ... 而不是return $this; 会怎样? (因为extend 函数返回sub。)
  • 错误状态,“无法读取未定义的属性'固定交叉'。”因此,您的关键字“this”的上下文抓住了错误的上下文。因此为什么“this”没有属性 fixation_cross
  • 似乎有多个问题。首先,函数 Stimulus 永远不会被调用。其次,Stimulus 函数中的 this 指的是全局命名空间(窗口)。为了让“this”引用对象实例,而不是全局命名空间,必须强制执行 new。我前段时间在 Javascript 模式中读到的一种模式是将这三行包含在任何打算成为对象的函数的顶部。因此,如果它是用 new 调用的,很好,如果不是(通常)然后强制执行: if (!(this instanceof arguments.callee)) { return new arguments.callee(); }

标签: javascript class oop inheritance prototypal-inheritance


【解决方案1】:

我明白了。您正在替换整个原型,因此它正在杀死构造函数。通过显式设置构造函数,您将其放回原处。另一种方法是直接设置原型方法,而不是设置整个原型。

为了使这个小提琴有用,请在单击运行之前打开控制台并设置一个断点。 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);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-21
    • 1970-01-01
    • 2011-04-08
    • 2011-02-21
    • 1970-01-01
    • 2018-08-15
    • 1970-01-01
    相关资源
    最近更新 更多