javascript子类中未定义父类的方法

javascript子类中未定义父类的方法,javascript,oop,Javascript,Oop,我是JSOO编程新手,我找不到这个错误的解决方案。 我正在声明以下类层次结构: 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(th

我是JSOO编程新手,我找不到这个错误的解决方案。 我正在声明以下类层次结构:

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)没有问题

先谢谢你


提前感谢您

这不是您设置继承的方式:

function FML_Text(id){
    this.prototype= new FML_Field(id);
    // ...
}
所做的只是在实例上创建一个名为prototype的属性

是这样做的:

function FML_Text(id){
    // ...
}
FML_Text.prototype = new FML_Field();
…并且不能将id参数传递给它,因为它发生在调用子对象构造函数之前。相反,通常的做法是定义一个初始值设定项函数,层次结构中的每个级别都支持后期构造,并调用该函数

无论如何,这是它的基础,但是真正健壮的继承需要更多的工作。例如,实际上调用子函数也定义了的父函数版本(例如,公共初始值设定项),或者子函数专门化父方法的任何时候,在JavaScript中实际上都有点麻烦,还有一些其他问题。但通过一些管道,您可以获得非常有效的继承链,包括将构造时参数传递给父初始值设定项

您可能希望使用这种东西的现有实现之一,而不是单独飞行。我在不久前的一篇文章中描述了我的方法,它的特点是对父方法超调用的调用非常有效。该库还提供了一个有效的类系统,尽管正是由于该系统的性能和兼容性问题,我才完成了上面的文章。他也写了很多关于这个主题的文章,并且投入了很多精力。几年前,当我查看它们时,我对这两个方面都有问题,但可能有更新

在我看来,需要寻找的东西:

简单的声明性语法。 语法对类非常友好,对于不需要公开的实现内容,类具有私有静态成员。私有实例方法几乎可以在任何系统中实现,但代价昂贵;看看它们,以及实现它们的各种方法。 系统不应该依赖于在函数实例上使用toString方法进行函数反编译。Prototype和Resig都知道,我不知道Edwards“和Edwards一样”。函数反编译从未被标准化,在某些移动浏览器上也不起作用。在Resig和Edwards的版本中,toString调用是隐式的,因此有点难找到,但它确实存在:它们将函数实例传递到正则表达式测试中,正则表达式测试将隐式调用函数的toString。 当调用实例方法时,系统不应该动态创建新的函数对象,只有在定义类时才应该这样做。Prototype是这样做的,每次您调用可能需要调用其父版本的实例方法时,都会调用它们的magic$super参数。他们的机制使得使用父版本非常容易,但代价是每次调用都要创建一个新函数,不管您是否真正调用$super。
我可以告诉你这个答案吗?我相信这将帮助您更好地理解JavaScript OOP。非常感谢,这是一个非常好和完整的答案。我将进一步研究OOP javascript,它看起来真是一团糟@旅行女店员:不用担心,很高兴这有帮助。我不会说是一团糟。JavaScript具有非常强大、灵活的OOP特性;这种灵活性有时是具有挑战性的。直到最近,调用方法的父版本还存在一个真正的问题。ECMAScript JavaScript的第5版现在才推出18个月,它添加了一些可能会更容易进行超级调用的功能,但实现要跟上规范还需要时间。我将更新我的文章,在某个时候讨论这些功能,而不是超快。Coffeescript提供了传统的OOP继承模型,您可能想考虑移植到咖啡脚本,或者可能检查生成的输出以实现类定义。