本文引用: www.iteye.com/topic/58698
例子:
- //得到当前对象的名称
- Object.prototype.getClassName = function()
- {
- return this.toString().match(/function\s*(\w+)/)[1];
- };
- /**
- * 实现单一多层结构的继承
- * @param arguments[0] 指定的类名,非字符串型,不可以是null。
- */
- Object.prototype.inherit = function()
- {
- try{
- if(!(arguments[0] instanceof Object)) throw new Error("you can just inherit from a Object");
- if(this["parent"]) throw new Error("there have inherited class,you can't inherit class "+arguments[0].getClassName());
- }catch(e){
- alert(e.message);
- return;
- }
- var arg = new Array();
- for(var i=0; i
- arg[i] = arguments[i+1];
- var temp = new arguments[0](arg);
- for(var i in temp){
- if(!this[i])
- this[i] = temp[i];
- }
- this["parent"] = temp;
- }
- //用来访问父类的public资源
- Object.prototype.father = function(){
- if(this.parent==null) return;
- if(this.parent[arguments[0]]){
- var temp = this.parent[arguments[0]].toString();
- if(temp.indexOf("function")<0>
- return this.parent[arguments[0]];
- else{
- var arg = new Array();
- for(var i=0; i
- arg[i] = arguments[i+1];
- return this.parent[arguments[0]](arg);
- }
- }else{
- this.parent.father(arguments);
- }
- }
- //与javascript的关键字typeof区别在:o大写
- Object.prototype.typeOf = function(){
- var target = arguments[0];
- var result = this instanceof target;
- if(!result){
- var temp = this.parent;
- while(temp!=null){
- result = temp instanceof target;
- if(!result)
- temp = temp.parent;
- else
- break;
- }
- }
- return result;
- }
- //将子类转换成父类,注意:如果子类覆盖了父类的方法,那么换转后的类,该方法的实现仍然是子类中的实现版
- Object.prototype.toParent = function(){
- var result = null;
- var target = arguments[0];
- var flag = this instanceof target;
- if(!flag){
- var temp = this.parent;
- while(temp!=null){
- flag = temp instanceof target;
- if(!flag)
- temp = temp.parent;
- else{
- result = {};
- for(var p in temp){
- if(this[p])
- result[p] = this[p];
- else
- result[p] = temp[p];
- }
- break;
- }
- }
- }else
- result = this;
- return result;
- }
- /**
- * 下面的继承关系是A inheritB,B inherit C,D是一个测试多态的方法
- */
- function A(){
- this.inherit(B,"x");
- this.inherit(C);
- var locate1 = "1oh";
- this.locate2 = "2oh";
- //A类继承B中的methodB1(),并且在自己的method1中调用B的methodB1
- this.method1 = function(){
- alert("A:test继承——I am use B's variant: "+this.methodB1(true));
- }
- //A类覆盖B中的method2(),并且在自己的method2中调用B的method2
- this.method2 = function(){
- var str = "A:test覆盖method2,result is:"+this.father("method2","ok");
- alert(str);
- }
- //A类覆盖了类C中的method3
- this.method3 = function(str){
- return "excuting class A's method";
- }
- }
- function B(){
- this.inherit(C,"y");
- var locateB2 = "";
- var locateB1 = arguments[0];
- this.methodB1 = function(flag){
- if(flag)
- return locateB1;
- else
- return "A converted B is success";
- }
- this.method2 = function(){
- var str =arguments[0]+" B's "+locateB1+" "+this.method1();
- return str;
- }
- //B类覆盖了类C中的method3
- this.method3 = function(str){
- return "excuting class B's method";
- }
- }
- function C(){
- var locate1 = arguments[0];
- this.method1 = function(){
- return "C's "+locate1;
- }
- this.method3 = function(){
- return locate1;
- }
- }
- /**
- * 在这个方法中,只会对C类的method3方法,如果参数是C的子类也会处理这个参数的method3方法。
- */
- function D(){
- var target = arguments[0];
- if(!target.typeOf(C)){
- alert("upper my scope");
- return;
- }
- alert("test多态:"+target.method3());
- }
- var a = new A;
- a.method1();//在其中调用了从B中继承过来的methodB1()
- a.method2();//A类覆盖B中的method2(),并且在自己的method2中调用B的method2
- var temp = a.toParent(B);
- alert(temp.methodB1(false)+": "+temp.method3());//转换成父类后,对象执行的方法仍然是子类版的。
- var b = new B("b^-^");
- D(a);
- D(b);
- //现在业务需要,扩展出一个E
- function E(){
- this.inherit(C,"change is so much!");
- }
- D(new E());//扩展性与通用性的表现
【注意事项】:
1) 需要用这种继承的写法,请将下面的方法当作javascript 的api,不要覆盖。
2) 在子类的
第一行执行继承。如果要覆盖父类的某个方法,并且要用父类的这个方法,那么请在子类的方法中回调父类的那个方法。
方法名称
|
方法作用
|
参数说明
|
getClassName
|
获得对象的名称。
|
无
|
inherit
|
实现对象之间的单一多层的继承
|
1
:被继承的父类名,非字符串
2
:父类初始化需要的参数
|
father
|
如果子类覆盖了父类的某个方法,用它来回调父类的这个方法
|
1
:回调的方法名称,字符串格式
2
:回调方法需要的参数
|
typeOf
|
判断子类的类型,与
typeof是不一样的。
|
类的名称,非字符串形式。
|
toParent
|
将子类转换成父类
|
父类的名字,非字符串形式。
|
3.3、活用闭包
所谓闭包,通俗的讲,使用函数的范围,已经不在函数的定义范围。
优点:进一步
提高代码的封装性。
缺点:ie6的垃圾收集机制存在着bug,当进行ui编码时会出现一些问题。
闭包的特点
1、作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。
闭包的写法
- function A(){
- var answer1 = function(str){
- alert("这里提供复杂功能1");
- }
- var answer2 = function(str){
- alert("这里提供复杂功能2");
- }
- this.getAnswer = function(flag){
- if(flag)
- return answer1;
- else
- return answer2;
- }
- }
- var control = new A();
- var a1 = control.getAnswer(true);
- var a2 = control.getAnswer(false);
- a1();//弹出文字:这里提供复杂功能1
- a2();//弹出文字:这里提供复杂功能2
- /**
- * 1)通过闭包,对象A将自己的资源提供给了外部。
- * 2)并且外部的代码对a1之类的变量做出了改变,不会影响到A对象内部
- * 下面对A类稍作修改,我们看看效果
- */
- function A(){
- var answer1 = function(str){
- alert("这里提供复杂功能1");
- }
- var answer2 = function(str){
- alert("这里提供复杂功能2");
- }
- this.getAnswer = function(flag){
- if(flag)
- return answer1;
- else
- return answer2;
- }
- this.answer = function(){
- answer1();
- }
- }
- var control = new A();
- var a1 = control.getAnswer(true);
- a1();
- a1 = "1";
- control.answer();//弹出文字:这里提供复杂功能1
3.4、函数式编程
它的基本特点是:将函数(或对象)赋值给一个变量。前面我们已经采用了这种写法。
优点:代码可读性好。适合web页ui方面的开发
错误的写法
- function A(){
- alert(B());
- var B = function(){
- return "ok";
- }
- }
- A();
正确的写法
- function A(){
- var B = function(){
- return "ok";
- }
- alert(B());
- }
- A();
附:javascript是非常灵活的:
1)基于对象的:有对象与类的概念,也有独立于对象的函数概念
2)解释型:请把握住运行时与时间轴这个概念:它能自动转化变量的类型与这个特点紧密相连;一段代码是当作函数,还是一个类,也与这个有关。
2)弱类型:会将变量自动转化为当前合适的类型或者基本数据类型,这个特点基于它是解释型的语言。
这些充分体现了javascript的灵活型。建议使用它,不要走极端:将其对象的一面在需要的时候充分运用,但没有必要任何情况下都这样做。所谓灵活:在不同的情况,可以有适合的方式可用。
(完毕)