`
zhangdaiping
  • 浏览: 129777 次
  • 性别: 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源代码】简单谈谈JavaScript寄生式组合继承.docx

    SuperType.call(this, name); // 调用父类构造函数 this.age = 25; } ``` #### 三、寄生式组合继承 **寄生式组合继承**结合了上述两种继承方式的优点,既可以在子类实例中拥有自己的属性,又可以共享父类的...

    Vue中的this.$options.data()和this.$data用法说明

    Object.assign(this.$data, this.$options.data.call(this)); } ``` 这样做后,`data()`方法中的`this`就会指向正确的Vue实例,能够正确访问`props`和`methods`。 此外,Vue在初始化组件时,先处理props和methods...

    javascript 中 this 的用法.docx

    箭头函数是 ES6 引入的新特性之一,在箭头函数中,`this` 的值不是由函数调用的方式决定的,而是继承自定义箭头函数时所在的作用域: ```javascript var obj = { test: function() { var arrowFunc = () =&gt; { ...

    详解javascript中的this对象.pdf

    在 JavaScript 中实现面向对象编程,通常会使用构造函数、原型链、以及类语法(ES6 之后引入)。`this` 在这些场景中起到关键作用,尤其是在创建实例和继承时。 例如,构造函数用于初始化新创建的对象: ```...

    JavaScript实现继承的几种方式

    Parent.call(this, name); } Child.prototype.sayHello = function() { console.log('Hi'); } let child = new Child('child'); console.log(child.name); // child child.sayHello(); // Hi ``` 3. 组合继承 ...

    【JavaScript源代码】JavaScript中的几种继承方法示例.docx

    **原理**: 构造函数继承是通过在子类构造函数内部调用父类构造函数(通常使用`call`或`apply`方法)来实现属性和方法的继承。 - **核心概念**: 通过这种方式,子类可以继承父类的所有属性和方法,并且可以在子类...

    cefsharp JavaScript调用C#方法并返回参数

    2. 调用C#方法:在JavaScript中,可以使用`window.chrome.webview`对象的`call`方法来调用C#方法。假设我们有一个名为`addNumbers`的C#方法,接受两个整数参数并返回它们的和,JavaScript代码可能如下: ```...

    JavaScript继承机制研究.pdf

    JavaScript继承机制研究 在本文中,我们将深入探讨JavaScript继承机制的实现方式,并对基于原型的继承、构造函数方式继承、组合继承、...本文对JavaScript继承机制的研究将有助于读者更好地理解和使用JavaScript语言。

    高手详解javascript中的this指针.pdf

    6. **call/apply/bind方法**:这些方法可以显式地设置`this`的值,允许开发者在任何环境中调用函数,并控制`this`的指向。 了解了这些原则后,我们可以更好地编写和理解JavaScript代码。例如,我们可以使用`bind`...

    javascript 原型模式实现OOP的再研究

    在B的`print`方法中,通过`this.prototype.print.call(this)`调用了A的`print`方法。 然而,这种做法在多层继承时会出现问题,因为`this.prototype`始终指向B.prototype,而不是A.prototype。当增加C类时: ```...

    【JavaScript源代码】详解JavaScript中的链式调用.docx

    JavaScript中的链式调用是一种常见的编程技巧,尤其在处理对象属性和方法时,可以使代码更加简洁、易读。链式调用的核心思想是通过在每次方法调用后返回对象自身,使得可以连续调用多个方法而无需重复指定对象名。在...

    EXT dojochina Ext方法重写.rar

    EXT.js提供了`this.callParent()`和`this.superclass.methodName.call(this)`两种方式来实现这一点。 - **避免副作用**:重写方法时要确保不会意外影响其他代码,尤其是当你重写的是核心库的方法。 - **测试**:确保...

    Js继承深讨.docx

    JavaScript中的继承是面向对象编程的重要概念,它允许创建新的对象类,这些类可以从现有类继承属性和方法。本文将深入探讨JavaScript中常见的两种继承实现方式:`prototype`方式和`apply`方式,并分析它们的优缺点。...

    JsCall方法详解(js的继承).pdf

    在这里,`Class1.call(this)`将`Class1`的构造函数调用放在`Class2`的上下文中,从而`Class2`实例拥有了`Class1`的`name`属性和`showName`方法。 `call`方法还可以用于实现多重继承,就像下面这个例子: ```...

    JavaScript面向对象编程指南.pdf

    Person.call(this, name, age); this.grade = grade; } // 继承Person的属性和方法 Student.prototype = Object.create(Person.prototype); Student.prototype.constructor = Student; var student = new ...

    javascript 继承派生

    Parent.call(this, name); // 使用call将Parent的构造函数绑定到Child实例上 this.age = age; } Child.prototype = Object.create(Parent.prototype); Child.prototype.constructor = Child; var child = new ...

    javascript中的this指向.docx

    - `call`方法允许你调用函数,并可以指定`this`的值,后面的参数将按顺序传递给函数。 - `apply`与`call`类似,但传递参数的方式不同,它接受一个数组或类数组对象作为第二个参数,用于传递给函数。 - `bind`则...

    VS2015安装证书,JavaScript_ProjectSystem.msi,JavaScript_LanguageService.msi

    在这个场景中,我们关注的是VS2015的安装过程中涉及到的证书问题以及两个特定的组件:JavaScript_ProjectSystem.msi和JavaScript_LanguageService.msi。 首先,关于“VS2015安装证书”,这通常是指安装过程中需要...

    【JavaScript源代码】一篇文章教你JS函数继承.docx

    Parent.call(this, name, age); } Child.prototype.sayLove = function () { console.log(this.name + " like " + this.nature[0]); }; var child1 = new Child("child1", "10"); child1.sayLove(); // "child1 ...

Global site tag (gtag.js) - Google Analytics