我是js OO编程的新手,我找不到这个错误的解决方案。
我声明了以下类层次结构:
function FML_Field(id){
this.id= id;
this.optional= true;
this.node= null;
if(this.id === undefined){
throw ""; //should provide Id;
}
var this.node= document.getElementById(this.id);
if(this.node === null){
throw "";
}
this.setAsOptional= function(){
this.optional= true;
};
this.setAsRequired= function(){
this.optional= false;
};
this.isOptional= function(){
return this.optional;
};
}
及其儿子:
function FML_Text(id){
this.prototype= new FML_Field(id);
FML_Text.prototype.constructor= FML_Text;
this.maxLength= false;
this.minLength= false;
this.setMaxLength= function(maxLength){
this.maxLength= maxLength;
}
this.getMaxLength= function(){
return this.maxLength;
}
this.hasMaxLength= function(){
return this.maxLength !== false;
}
}
然后我继续下面的代码:
var first_name = new FML_Text("first_name");
first_name.setAsRequired(); /*throws an error: setAsRequired is not defined*/
怎么了?我已经使用javascript控制台检查:first_name已定义但setAsRequired()未定义。以下函数调用如first_name.setMaxLength()没有问题。
提前谢谢。
提前谢谢
答案 0 :(得分:0)
这不是你设置继承的方式:
function FML_Text(id){
this.prototype= new FML_Field(id);
// ...
}
所有这一切都是在实例上创建一个名为prototype
的属性。
这样做:
function FML_Text(id){
// ...
}
FML_Text.prototype = new FML_Field();
...并且您无法将id
参数传递给它,因为它发生在调用子对象构造函数之前。相反,通常的做法是定义一个“初始化器”函数,层次结构中的每个级别都支持构造后,并调用它。
无论如何,这是它的基础,但真正强大的继承需要更多的工作。例如,实际上调用父级已经定义的函数的父版本(例如,一个公共的初始化程序,或者一个孩子专门研究父方法的任何时候)实际上是JavaScript中的一个小提琴,并且有其他一些“陷阱”。但是通过一些管道,你可以获得非常有效的继承链(包括将构造时参数传递给父初始化器)。
您可能希望使用此内容的现有实现之一,而不是单独飞行。我在前一段时间内在this article中描述了我的内容,其中包含对父方法(“supercalls”)的高效调用。 Prototype库也提供了一个有效的“类”系统,尽管这个系统的性能(和兼容性)问题导致我做上面的文章。 Dean Edwards也在这个主题上撰写了大量文章,并且John Resig已经投入。我几年前看过这些文章时遇到了两个问题,但可能有更新。
要寻找的东西(在我看来):
toString
实例上的Function
方法)。 Prototype和Resig都做了,toString
调用是隐式的,所以它有点难以找到,但它就在那里:它们将函数实例传递给正则表达式测试,它将隐式调用函数的{{1 }}。)toString
参数)。他们的机制使得使用父版本很容易,但不管是否实际调用$super
,都需要(再次)在每次调用时创建一个新函数 。