【问题标题】:Calling base class function - class inheritance in JavaScript调用基类函数 - JavaScript 中的类继承
【发布时间】:2013-03-30 08:27:24
【问题描述】:

请查看以下示例:

MyBaseClass = function(a) {
     this.a = a;
};

$.extend(MyBaseClass.prototype, {
    init: function() {
        console.log('I am initializing the base class');
    }
});

MyChildClass = $.extend(MyBaseClass, {
    init: function() {
        MyBaseClass.prototype.init();
        console.log('I am initializing the child class');
    }
});

var = new MyChildClass();
var.init();

Тhis 应该同时输出“我正在初始化基类”和“我正在初始化子类”。

我需要能够继承类MyBaseClass,但仍然能够在新的init()方法的开头调用他的init()方法。

我该怎么做?

【问题讨论】:

  • $.extend 并不像你想的那样。
  • 这段代码的一个明显问题是在底部使用var
  • $.extend 到底是什么?
  • @FelixKling 一个是由 jQuery 定义的。我假设这个。
  • @JanDvorak 我确定 Felix 知道,但指出 OP 应该添加相关标签。

标签: javascript class inheritance


【解决方案1】:

jQuery's extend 不构建继承,而是“将两个或多个对象的内容合并到第一个对象中”。

使用prototype based inheritance 来实现你的继承并显式调用“super”方法:

MyBaseClass = function(a) {
     this.a = a;
};
MyBaseClass.prototype.init = function() {
    console.log('I am initializing the base class');
};

MyChildClass = function(a) {
  this.a = a;
}
MyChildClass.prototype = Object.create(MyBaseClass.prototype); // makes MyChildClass "inherit" of MyBaseClass
MyChildClass.prototype.init = function() {
    MyBaseClass.prototype.init.call(this); // calls super init function
    console.log('I am initializing the child class');
};

var child= new MyChildClass();
child.init();

Output:

I am initializing the base class
I am initializing the child class 

【讨论】:

  • 这里应该使用Object.create吗?
  • OP说到“类”和继承,我个人觉得prototype更合适。
  • 也许 Jan 打算使用 MyChildClass.prototype = Object.create(MyBaseClass.prototype);。这将是继承恕我直言的更好方法。实例化父级的新实例可能有缺点。
【解决方案2】:

jsFiddle Demo

几件事。 extend 真的只是增加了属性,并没有多大作用。因此,您需要为您的类准备好一个函数,从基类继承,然后在该类原型上使用扩展。

function MyChildClass(){};
MyChildClass.prototype = new MyBaseClass();
$.extend(MyChildClass.prototype, {
 init: function() {
    MyBaseClass.prototype.init();
    console.log('I am initializing the child class');
 }
});

这是我喜欢用于继承的另一种方法 - 当方法的特异性成为问题时 - 将基类存储在其自己的属性中

function MyChildClass(){};
MyChildClass.prototype = new MyBaseClass();
MyChildClass.prototype.base = new MyBaseClass();
$.extend(MyChildClass.prototype, {
 init: function() {
    this.base.init();
    console.log('I am initializing the child class');
 }
});

【讨论】:

    【解决方案3】:

    实现这一目标的另一种基于原型的模式:

    MyBaseClass = function(a) {
         this.a = a;
    };
    
    MyBaseClass.prototype = {
        init: function() {
            console.log('I am initializing the base class');
        }
    };
    
    MyChildClass = function() {};
    MyChildClass.prototype = $.extend(new MyBaseClass(), {
        init: function() {
            this.super.init.call(this);
            console.log('init child');
        },
        super: MyBaseClass.prototype,
        constructor: MyChildClass
    });
    
    var a = new MyChildClass();
    a.init();
    

    输出:

    I am initializing the base class
    init child
    

    这里this.super 存储对基类的引用。

    【讨论】:

    • 诚实的问题:你为什么要指定构造函数?
    • @dystroy - 我实际上在 jquery 源代码中看到了这一点。我认为这是因为有时构造函数有时会指向错误的函数(目前不记得让它这样做的确切场景)。
    • @dystroy 能够使用instanceof。 a instanceof MyChildClass
    • 你的模式有问题:你失去了使用this.super.init()或this.super.anyfunc()的上下文。这个super 看起来是个坏主意。
    • @dystroy 你说得对,谢谢。好吧,这只是另一种模式,为什么不呢,有些人会使用它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 2011-01-08
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多