`
zhangdaiping
  • 浏览: 130052 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Javascript类的继承,使用this.callParent调用超类方法

 
阅读更多
以前在做Ext3开发的时候,一直用使用Ext.extend()来做类的继承,在以后写代码,都习惯了使用Ext.extend类似功能的代码来做类继承,但是遇到一个问题一直无法解决,如下面的代码:
 
MyClass1 = function() {};
MyClass1.prototype = {
    say: function() {
        alert('MyClass1 say hello world!');
    }
};

MyClass2 = Ext.extend(MyClass1, {
    say: function() {
        MyClass2.superclass.say.call(this);
        alert('MyClass2 say hello world!');
    }
});
 
每次子类需要调用超类方法,都要像下面这样写:
 
MyClass2.superclass.say.call(this);
 
这种写法有几个弊端:
  • 类名要内置到函数代码模块中,如果一旦修改类名,就非常麻烦
  • 每次的调用都要写一长串代码,有时候为了省事复制粘贴,忘记改类名,就会出错
  • 有时候需要传参,使用call与apply调用用法不统一
 
所以,很长一段时间在想如何改进super的调用?能做到java那样,如:
 
public MyClass2 extends MyClass1{
    public void say() {
        super.say();
        System.out.println('MyClass2 say hello world!');
    }
}
 
自己试了好几种方法,总是不能完美解决,就放弃了一段时间,再后来也没有多想这事。
 
Ext4出来之后,看了一些资料,发现Ext4 Class非常强大,完美的解决我想的问题,其实,那时候挺兴奋,想研究以下源码的,打开代码库,发现Ext对类的支持过于强大(对我而言),结构异常复杂,那时候也由于重心没在这块,所以,就先放下没有继续研究。今天终于静下心来,用心阅读了Ext4 Class相关的源码(Ext的开发者很厉害,不得不佩服)。

Ext使用callParent就能调用到父类的方法,非常简单,用法如下:
 
MyClass2 = Ext.define({
    say: function() {
        this.callParent(); // 调用父类的say()

        // 如果要为父类方法传参,只需要像下面这样写
        //this.callParent(arguments);
        //this.callParent([param1, param2]);

        alert('say: hello world!');
    }
});
 
我把其中和类继承相关的代码剥离出来,重新编码,其他有关Config,Statics等特性全部移除,代码变简单了很多,也容易懂了很多。下面是应用的例子,Class的源码和例子都使用了requirejs,附件中是class.js的源码:
 
require(['class/Class'], function(Class) {
    var MyCls1 = Class.define({
        say: function() {
            alert('MyCls1 say: hello world!');
            // 输出'MyCls1 say: hello world!'
        }
    });
    new MyCls1().say();

    var MyCls2 = Class.define({
        extend: MyCls1,
        say: function() {
            this.callParent();
            alert('MyCls2 say: hello world!');
            // 输出'MyCls1 say: hello world!'
            // 输出'MyCls2 say: hello world!'
        }
    });
    new MyCls2().say();

    var MyCls3 = Class.define({
        extend: MyCls2,
        say: function() {
            this.callParent();
            alert('MyCls3 say: hello world!');
            // 输出'MyCls1 say: hello world!'
            // 输出'MyCls2 say: hello world!'
            // 输出'MyCls3 say: hello world!'
        }
    });
    new MyCls3().say();
    
    Class.override(MyCls2, {
        constructor: function(config) {
            this.name = config.name;
        },
        say: function() {
            this.callParent();
            alert('the new method MyCls2 say: hello world! by ' + this.name);
            // 输出'MyCls1 say: hello world!'
            // 输出'the new method MyCls2 say: hello world! by max'
            // 输出'MyCls3 say: hello world!'
        }
    });
    
    new MyCls3({
        name: 'max'
    }).say();
});
 
例子html页面
 
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Unit</title>

<script type="text/javascript" src="../src/lib/requirejs.js"></script>
<script type="text/javascript">
require.config({
    baseUrl: '../src'
});
</script>
<script type="text/javascript" src="unit/Class.js"></script>

</head>
<body>

</body>
</html>
 
原创文章,转载请注明出处http://zhangdaiping.iteye.com
分享到:
评论

相关推荐

    JavaScript中的继承方式详解

    类式继承通常通过构造函数的内部调用来实现,即子类型构造函数内部调用超类型的构造函数,如`Super.call(this)`。这种方式并不常见,通常与其他继承方式结合使用。类式继承主要通过`call`或`apply`方法来实现构造...

    详解JavaScript基于面向对象之继承

    在这个例子中,`Child` 构造函数通过 `Parent.call(this, name)` 调用 `Parent` 构造函数,并将 `this` 绑定到 `Child` 的实例上,从而实现继承。 3. 组合方式(组合继承) 组合继承是原型链方式和构造函数方式的...

    js类式继承的具体实现方法

    JavaScript 类式继承是一种模仿传统面向对象编程中的类继承机制的方式,由于 JavaScript 是基于原型的,因此它的继承方式与基于类的语言有所不同。类式继承主要通过原型链(prototype chain)来实现,允许一个对象...

    js代码-原型赋值继承方式

    在JavaScript中,可以使用`Object.create()`方法或直接修改`__proto__`来实现原型赋值继承: 1. **使用`Object.create()`**: ```javascript function Parent() {} Parent.prototype.name = "parent"; ...

    subclass-dance-party

    在面向对象编程中,子类化允许我们创建一个新的类(子类),它继承自另一个已存在的类(父类或超类),从而获得其属性和方法,并可以添加自己的特性或重写父类的方法。这个项目可能是为了演示如何在JavaScript中实现...

    Flash_Lite_2.x_Action_Script语法参考手册

    - **super语句**:调用超类构造函数或方法。 - **switch语句**:基于不同条件执行不同的代码块。 - **throw语句**:抛出异常。 - **try..catch..finally语句**:处理异常。 - **var语句**:声明变量。 - **while语句...

Global site tag (gtag.js) - Google Analytics