繁体   English   中英

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

[英]methods of parent class undefined in subclass in javascript


我是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())没有问题。

先感谢您。

先感谢您

这不是设置继承的方式:

function FML_Text(id){
    this.prototype= new FML_Field(id);
    // ...
}

所有要做的就是在实例上创建一个称为prototype的属性。

这样做是这样的:

function FML_Text(id){
    // ...
}
FML_Text.prototype = new FML_Field();

...并且您不能将id参数传递给它,因为它发生在调用子对象构造函数之前。 取而代之的是,通常的事情是定义一个“初始化程序”函数,您的层次结构中的每个级别都支持后构造,然后调用该函数。

无论如何,这就是它的基础,但是要真正强大的继承需要更多的工作。 例如,实际上调用子级也定义的函数的父级版本(例如,通用的初始化程序,或者子级专门使用父级方法的任何时候)实际上在JavaScript中有点麻烦。其他一些“陷阱”。 但是通过一点点探索,您可以获得非常有效的继承链(包括将构造时参数传递给父初始化程序)。

您可能想要使用此工具的现有实现之一,而不是单飞。 我在不久前的文章中介绍了我的文章该文章的特色对父方法的真正有效调用(“超级调用”)。 Prototype库还提供了有效的“类”系统,尽管正是该系统的性能(和兼容性)问题导致我撰写上述文章。 迪恩·爱德华兹(Dean Edwards )也就该主题写过很多书, 约翰·雷西格John Resig)也参与其中。几年前,当我看这两个书时,我都遇到了问题,但可能会有更新。

寻找的东西(我认为):

  • 简单明了的声明性语法。
  • 对您的类而言,非常友好的语法具有私有静态成员,用于执行不需要公开的实现内容。 (私有实例方法几乎可以在任何系统中完成,但是它们很昂贵;请参阅Crockford对它们的讨论以及对实现它们的各种方式的比较 。)
  • 该系统应该依赖于函数反编译(使用toString上方法Function实例)。 原型和Resig都可以, 爱德华兹和爱德华兹都不知道 函数反编译从未标准化过,并且在某些移动浏览器上不起作用。 (在Resig和Edwards的版本中, toString调用是隐式的,因此很难找到,但是确实存在:它们将一个函数实例传递给regex测试,后者将隐式调用该函数的toString 。)
  • 该系统应该即时时实例方法的调用由创建新的函数对象,只有当类定义(如果当时)。 原型的确如此, 每次您调用一个可能需要调用其父代版本的实例方法(其神奇的$super参数)。 它们的机制使使用父版本的版本变得非常容易,但是(再次) 以每次调用创建一个新函数为代价,无论您实际上是否调用$super

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM