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