以前在做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原型继承机制参考.pdf
javascript原型继承机制借鉴.pdf
javascript原型继承机制归类.pdf
javascript关于继承解析_.docx
JavaScript继承机制研究.pdf
使用javascript调用webservice示例.pdf使用javascript调用webservice示例.pdf
它的基本思想是使用原型链继承原型上的属性和方法,通过盗用构造函数继承实例属性,这样的好处就是可以把方法定义在原型上复用,每个实例又有自己的属性。 function SuperType (name) { this.name = name; this....
Javascript继承[参考].pdf
发现大多人都用了Array.prototype.slice.call(argments,0),一直不明白这句是干什么的。而昨天温习了slice()方法,再参考Function.call(thisArg[, arg1[, arg2[, ...]]]),还是不得而知(我脑筋转得慢:|)。
详解Javascript继承的实现_.docx
JavaScript继承与多继承实例分析.docx
使用javascript调用webservice示例归类.pdf
通常来说,this 的值是在函数被调用时确定的,其值取决于函数被调用的方 式。本文将介绍 JavaScript 中 this 的用法,从而帮助开发者更好地理解并掌握 this 的使用。 一、在全局作用域中使用 this 在全局作用域中...
Html+Css+Javascript从入门到精通.pdfHtml+Css+Javascript从入门到精通.pdf
JavaScript中的继承之类继承_.docx
ASP.NET中前台javascript与后台代码调用.doc
在JavaScript中模拟类(class)及类的继承关系_.docx
JavaScript一种没有类的,面向对象的语言,它使用原型继承来代替类继承。这个可能对受过传统的面向对象语言(如C++和Java)训练的程序员来说有点迷惑。JavaScript的原型继承比类继承有更强大的表现力,现在就让我们...
总结 1、相同点 2、区别 call() 方法 /* 正常模式 */ let obj = { sum(a, b) { console.log(this) return a + b } } // 执行 sum 函数的 apply、bind 方法,打印的 this 同下 obj.sum.call() // 打印...